Сделайте интерфейс универсальным, затем используйте Func<INode,T>
в качестве селектора для ключа. Это предполагает, что вы хотите, чтобы ключ для словаря был извлечен из узла. Если это не сложное требование, вы можете указать сам ключ, используя спецификатор общего типа в подписи.
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>();
}
}
Вы также можете рассмотреть возможность сделать INode универсальным типом. Это позволит вам указать ключ как свойство универсального типа, которое реализация может отнести к соответствующему «реальному» ключу. Это избавит вас от необходимости указывать ключ или селектор для метода расширения.
Альтернатива:
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>>();
}
}
Используется как:
var topology = new TopologyImp<string>();
topology.AddNode( new StringNode { Name = "A", ID = 0 } );
var node = topology.FindNode( "A" );