繁体   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