2010-05-06 148 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>(); 
} 
}