通用委托实例

Luc*_*c C 2 c# generics delegates

我想知道C#(或底层的.NET框架)是否支持某种"泛型委托实例":这是一个委托实例仍然有一个未解析的类型参数,在调用委托时要解析(当时不是代表已创建).我怀疑这是不可能的,但无论如何我都在问它......

这是我想要做的一个例子,有一些"???" 插入C#语法似乎无法满足我想要的地方.(显然这段代码不能编译)

class Foo {
  public T Factory<T>(string name) {
    // implementation omitted
  }
}

class Test {
  public void TestMethod()
  {
    Foo foo = new Foo();
    ??? magic = foo.Factory; // No type argument given here yet to Factory!
                             // What would the '???' be here (other than 'var' :) )?
    string aString = magic<string>("name 1"); // type provided on call
    int anInt = magic<int>("name 2"); // another type provided on another call

    // Note the underlying calls work perfectly fine, these work, but i'd like to expose
    // the generic method as a delegate.
    string aString2 = foo.Factory<string>("name 1");
    int anInt2 = foo.Factory<int>("name 2");
  }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在C#中实际做这样的事情?如果没有,这是语言的限制,还是在.NET框架中?

编辑: 我问的原因是因为我想将委托传递给另一个程序集中的函数,并且不希望要求其他程序集必须引用任何特定类型(在我的示例中为"Foo"类).我希望以某种方式弯曲标准的Func <>委托,以便它适合"???" 部分.

Pet*_*old 7

这是不可能的,因为你要求的是声明一个magic未闭合的泛型类型的变量().

可以使用未闭合的泛型,但仅限于类型级别,例如:

delegate T FactoryDelegate<T>(string name);

var magicType = typeof (FactoryDelegate<>);
Run Code Online (Sandbox Code Playgroud)

然后在以后"关闭"该类型:

var stringMagic = magicType.MakeGenericType(typeof(string));
Run Code Online (Sandbox Code Playgroud)

更新:说,这里有一个示例,说明如何使用上述技术也可以使用未闭合的方法"类型".如果我们可以分配未关闭的类型,那么仍然没有那么优雅..:

    public class UnclosedMethod
    {
        private readonly MethodInfo _method;

        public UnclosedMethod(Type type, string method)
        {
            _method = type.GetMethod(method);
        }

        public T Invoke<T>(string name)
        {
            var fact = _method.MakeGenericMethod(typeof(T));
            return (T)fact.Invoke(this, new object[] { name });
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后在代码中执行此操作:

var magic = new UnclosedMethod(typeof(Foo), "Factory");
var x = magic.Invoke<string>("bar");
Run Code Online (Sandbox Code Playgroud)