Make the interface generic, then use a Func<INode,T>
as a selector for the key. This assumes that you want the key for the dictionary to be extracted from the node. If this isn't a hard requirement, then you could specify the key itself using the generic type specifier in the signature.
public interface ITopology<T>
{
Dictionary<T, INode> Nodes { get; set; }
}
public static class TopologyExtns
{
public static void AddNode<T>(this ITopology<T> topIf, INode node, Func<INode,T> keySelector )
{
topIf.Nodes.Add( keySelector(node), node );
}
public static INode FindNode<T>(this ITopology<T> topIf, T searchKey )
{
return topIf.Nodes[searchKey];
}
}
public class TopologyImp<T> : ITopology<T>
{
public Dictionary<T, INode> Nodes { get; set; }
public TopologyImp()
{
Nodes = new Dictionary<T, INode>();
}
}
You might also consider making INode a generic type. That would allow you to specify the Key as a property of the generic type which the implementation could defer to the appropriate "real" key. This would save you from having to supply either the key or a selector for the extension method.
Alternative:
public interface INode<T>
{
T Key { get; }
string Name { get; set; }
int ID { get; set; }
}
public class StringNode : INode<string>
{
public string Key { get { return this.Name; } }
public string Name { get; set; }
public int ID { get; set; }
}
public interface ITopology<T>
{
Dictionary<T, INode<T>> Nodes { get; set; }
}
public static class TopologyExtns
{
public static void AddNode<T>(this ITopology<T> topIf, INode<T> node )
{
topIf.Nodes.Add( node.Key, node );
}
public static INode<T> FindNode<T>(this ITopology<T> topIf, T searchKey )
{
return topIf.Nodes[searchKey];
}
}
public class TopologyImp<T> : ITopology<T>
{
public Dictionary<T, INode<T>> Nodes { get; set; }
public TopologyImp()
{
Nodes = new Dictionary<T, INode<T>>();
}
}
Used as:
var topology = new TopologyImp<string>();
topology.AddNode( new StringNode { Name = "A", ID = 0 } );
var node = topology.FindNode( "A" );