【问题标题】:C# - Is there a way to call a static method of a generic type in a class? [duplicate]C# - 有没有办法在类中调用泛型类型的静态方法? [复制]
【发布时间】:2020-01-01 17:31:52
【问题描述】:

例子:

Public class a<T> where T: containsStatic
{
    public void func()
    {
        T.StaticMethod();
    }

}

有可能吗?如果没有,还有其他方法吗?

编辑: 它给了我错误:“'T' 是一个类型参数,在当前上下文中无效。” 这是为什么?有没有办法解决这个问题?

【问题讨论】:

  • 你怎么知道T这个类型包含StaticMethod
  • System.Reflection 是要走的路。
  • 你说得对,我更正了。

标签: c# class static static-methods


【解决方案1】:

我预见到的问题是你如何保证T 支持StaticMethod

但是,如果您确定 StaticMethod 将始终存在于 T 上,则可以使用反射来相当简单地完成此操作:

using System.Reflection;

public void func()
{
    var staticMethod = typeof(T).GetMethod("StaticMethod", BindingFlags.Public | BindingFlags.Static);
    staticMethod.Invoke(null, null);
}

【讨论】:

  • 我加了条件,现在还有别的办法吗?
  • @NoamSimon 如果(来自您的示例)containsStatic 包含静态方法,那么它将起作用。
  • 如果你使用这个解决方案我会添加错误处理,因为如果类型没有该名称的静态方法,你会得到一个模糊的NullReferenceException,并且你' 如果有一个同名但参数数量不同的异常,则会得到一个不同的异常。
  • Martin,它实际上不起作用,它给我这个错误:“'T'是一个类型参数,在当前上下文中无效”。可能的问题是什么?
  • @NoamSimon 你还没有把func 放在一个班级里。
【解决方案2】:

假设我们挥动一根魔杖,而你现在可以这样做。假设一个类型C

public class C
{
    public static void Foo()
    {
    }
}

这会怎样:

public class A<T> where T : C
{
    public void Func()
    {
        T.Foo();
    }

}

与以下任何不同:

public class A<T> where T : C
{
    public void Func()
    {
        C.Foo();
    }
}

它不会。它必须是被调用的同一个方法。当方法的代码生成时,静态方法调用是静态生成的(是的,我知道)。看到T.Foo() 的编译器不可能在那里插入除C.Foo() 之外的任何其他调用。

所以你甚至不能用 C# 的语法来表达,a type parameter is disallowed by the spec in such a context

不能在成员访问 (Member access) 或类型名称 (Namespace and type names) 中使用类型参数来标识静态成员或嵌套类型。

如果您想在运行时动态地根据T 的值调用静态方法,请参考@Martin 的反射解决方案。

【讨论】:

    【解决方案3】:

    您可以调用任何静态方法,只要它不依赖于通用类型。 如果你有类似的课程

     public class Test<T>
     {
            public static int Result => 5;
     }
    

    你可以打电话

     int n = Test<int>.Result;
    

    在任何你想要的地方,你实际插入什么类型并不重要,因为任何类型都会做同样的事情

     int n = Test<string[]>.Result;
    

    会做同样的事情。

    如果你的函数像 in 一样依赖于 T

        public class Test1<T>
        {
            public static void Action(T param)
            {
    
            }
        }
    

    你可以使用

      Test1<int>.Action(8);
    

    在任何你想要的地方。

    也在其他泛型类中:

        public  class OtherClass<T> 
        {
            public void Method(T param)
            {
                Test1<T>.Action(param);
            }
        }
    

    但大多数情况下,可以在非泛型类中编写泛型函数,例如

        public class Test2
        {
            public static void Action<T>(T param)
            {
    
            }
        }
    

    这适用于程序中的任何地方

       Test2.Action("string");
       Test2.Action(9);
    

    你可以把这个函数放在你想要的任何类中,因为它是静态的。无需将此函数放在泛型类中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多