【问题标题】:Generics and Action Delegate泛型和动作委托
【发布时间】:2011-03-28 19:02:04
【问题描述】:

我有以下代码:

public void generate()
{
  base.generateFoo(Method); // How can i indicate the type here?
}

public void Method<T>(T t , IDictionary<T, SomeObject> coll) : where T : ISomething
{
 // do something
}


class MyBase
{
  public void generateFoo<T>(Action<T, IDictionary<T, SomeObject>> Method) : where T : ISomething
  {
     Method.invoke(ObjectThatImplementsT, DictionaryWIthTKey);
  }
}

我收到一个错误,例如无法将 ObjectThatImplementsT 转换为 T。

我可以将泛型方法作为参数传递给另一个方法吗?

这里有什么问题?

谢谢。

【问题讨论】:

    标签: c# .net generics delegates action


    【解决方案1】:

    您可能只需要指定类型:

    public void generate()
    {
       base.generateFoo<YourType>(Method);
    }
    

    话虽如此 - 上面的代码不会编译,因为generateFoo 不是泛型方法,也不是泛型类,所以上面的代码可能不起作用。假设generateFoo 被定义为泛型方法(采用T 类型)。

    【讨论】:

    • 我只是有点太慢了:)
    • 这是一个通用方法。对不起。
    • 但我得到:变量不能用作类型参数错误。
    • 在基类中。在我调用动作时。
    • 可能需要更真实的代码示例;如果您在调用委托时尝试显式指定泛型类型,使用命名变量而不是静态定义的类型标识符,则只会收到您指定的错误。
    【解决方案2】:

    您可以使generateFoo 泛型为 T,具有与 Method 相同的限制。您的示例实际上不会编译,因为 MyBase 不知道 T (除非您实际上在已知命名空间中有一个名为 T 的类)。

    【讨论】:

      【解决方案3】:

      以上所有内容都适用,有很多小的修改(为什么不自己编译样本,这样我们就可以知道哪些“问题”是假的,你真正的问题是什么?!)

      这是一个编译位 - 请注意调用 generateFoo 的三种变体:

      using System.Collections.Generic;
      using System;
      
      namespace X 
      { 
          class Y : MyBase
          {
              public static void Main(string[]args) { }
      
              public void generate()
              {
                  base.generateFoo<Something>(Method<Something>); // works
                  base.generateFoo<Something>(Method); // works as well
                  base.generateFoo(Method<Something>); // doesn't (cannot be inferred)
              }
      
              public void Method<T>(T t , IDictionary<T, SomeObject> coll) 
                  where T : ISomething
              {
                  // do something
              }
      
          }
      
          class MyBase
          {
              public void generateFoo<T>(Action<T, IDictionary<T, SomeObject>> Method) 
                  where T : class, ISomething
              {
                  Method.Invoke((T) null, new Dictionary<T,SomeObject>());
              }
          }
          internal interface ISomething {}
          internal class Something : ISomething {}
          internal class SomeObject {}
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-07
        • 1970-01-01
        • 2018-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-08
        • 2020-12-04
        相关资源
        最近更新 更多