簡體   English   中英

具有泛型的擴展方法-調用方何時需要包括類型參數?

[英]extension methods with generics - when does caller need to include type parameters?

是否有規則知道調用擴展方法時何時必須在客戶端代碼中傳遞通用類型參數?

因此,例如在Program類中,為什么我(a)不能傳遞top.AddNode(node)的類型參數,但是稍后(b)top.AddRelationship行必須傳遞它們呢?

class Program
{
    static void Main(string[] args)
    {
        // Create Graph
        var top = new TopologyImp<string>();

        // Add Node
        var node = new StringNode();
        node.Name = "asdf";
        var node2 = new StringNode();
        node2.Name = "test child";
        top.AddNode(node);
        top.AddNode(node2);


        top.AddRelationship<string, RelationshipsImp>(node,node2);  // *** HERE ***

    }
}


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 static void AddRelationship<T,R>(this ITopology<T> topIf,  INode<T> parentNode,  INode<T> childNode) 
        where R : IRelationship<T>, new()
    {
        var rel = new R();
        rel.Child = childNode;
        rel.Parent = parentNode;
    }
  }


public class TopologyImp<T> : ITopology<T>
{
    public Dictionary<T, INode<T>> Nodes { get; set; }
    public TopologyImp()
    {
        Nodes = new Dictionary<T, INode<T>>();
    }
}

關於第二個示例,編譯器不知道您要為R使用哪種類型。 它只知道它必須實現IRelationship<T>並具有公共默認構造函數。 它不能從您傳遞給方法的任何參數中推斷出它的類型,因為它們的類型為T。在這種情況下,您需要告訴它要用於R的類。創建R的實例作為參數,它將能夠推斷類型,而您無需提供它們。

在第一種情況下,您不需要提供類型,因為參數是類型的,因此編譯器可以推斷出您想要的類型。

通常,您不必顯式指定類型。 當類型實際上是一個參數時就需要它-例如linq函數.Cast它的類型告訴它要做什么: Cast<Employee>()

在您的情況下,這很簡單: AddRelationship<T,R>具有三個參數,均為T類型-如何推斷R

我尚未完成此特定設置,但是我對類型推斷的理解是調用者無需指定類型。 ITopology<T> topIf將引用已經聲明類型的實例。 擴展方法應該隱式拾取相同類型的參數。

許多LINQ擴展方法都基於IEnumerable的通用擴展方法。 這與您使用的模式相同。 那是一個開始尋找的好地方。

和往常一樣,進行測試。

我認為這是因為您沒有在函數中包含任何類型為R的參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM