2010-05-06 111 views
1

我怎么能使这个代码更通用的意义上,字典的关键可能是一个不同的类型,这取决于图书馆的用户想实现什么?例如,有人可能在使用扩展方法/接口的情况下使用扩展方法/接口,例如,可以说节点的“唯一键”实际上是一个“int”而不是“字符串”。如何使此代码更通用

public interface ITopology 
{ 
    Dictionary<string, INode> Nodes { get; set; } 
} 

public static class TopologyExtns 
{ 
    public static void AddNode(this ITopology topIf, INode node) 
    { 
     topIf.Nodes.Add(node.Name, node); 
    } 
    public static INode FindNode(this ITopology topIf, string searchStr) 
    { 
     return topIf.Nodes[searchStr]; 
    } 
} 

public class TopologyImp : ITopology 
{ 
    public Dictionary<string, INode> Nodes { get; set; } 

    public TopologyImp() 
    { 
     Nodes = new Dictionary<string, INode>(); 
    } 
} 

回答

6

使接口为通用接口,然后使用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成为一个通用类型。这将允许您将Key指定为泛型类型的属性,该类型的实现可以推迟到适当的“真实”键。这将使您无需为扩展方法提供密钥或选择器。

备选:

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"); 
2
public interface ITopology<T> 
{ 
    Dictionary<T, INode> Nodes { get; set; } 
} 

public static class TopologyExtns<T> 
{ 
    public static void AddNode<T>(this ITopology<T> topIf, T key, INode node) 
    { 
     topIf.Nodes.Add(key, 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>(); 
    } 
} 
+0

TopologyExtns是错误的 - ITopology现在是通用的,你需要要么使扩展方法一般或参数参考具体。 – 2010-05-06 18:20:54

+0

感谢@Matt,很好。 – derek 2010-05-06 18:29:13

2

为什么不把你的拓扑接口通用?我自己对扩展方法有点模糊,但这应该是可行的。

public interface ITopology<TKey> 
{ 
    Dictionary<TKey, INode> Nodes { get; set; } 
} 

public static class TopologyExtns 
{ 
    public static void AddNode<T>(this ITopology<T> topIf, T key, INode node) 
    { 
     topIf.Nodes.Add(key, node); 
    } 
    public static INode FindNode<T>(this ITopology<T> topIf, T searchObj) 
    { 
     return topIf.Nodes[searchObj]; 
    } 
} 


public class TopologyImp : ITopology<String> 
{ 

public TopologyImp() 
{ 
    Nodes = new Dictionary<String, INode>(); 
} 
}