只有通用参数时调用静态成员

时间:2009-10-07 23:55:18

标签: c# generics

当我只有一个泛型参数时,有没有办法在类型上调用静态成员。例如,如果我有这样的东西

public Get<T>(int id)
{
   // I would like to do this
   string s = T.SomeMethodName();
}

我可以这样做,但有点“讨厌”,然后无论是静态还是无关紧要。或者我可以使用Yuriy建议的反射。

ISomeKnownInterface i = (ISomeKnownInterface ) new T(); 
string s = i.SomeMethodName();

现在问题是哪种方法更好,创建使用反射的新实例

public TFormDto Get<TFormDto>(int entityId) where TFormDto : AbstractEntityFormDto, new()
        {
// create new instance
            AbstractEntityFormDto a = (AbstractEntityFormDto) new TFormDto();
            string entityName = a.GetEntityFullTypeName();

// use reflection 

            Type type = typeof(TFormDto);
            string entityName = type.GetMethods(BindingFlags.Public | BindingFlags.Static)
                .Single(m => m.Name == "GetEntityFullTypeName")
                .Invoke(null, null);

3 个答案:

答案 0 :(得分:1)

不会只是一直是AbstractBaseClass.GetFullName()。否则,您必须在T上使用反射来获取另一个类的静态方法。 This可能会有所帮助。

以下是一个简单的例子:

class TestClass
{
    public static void Hello()
    {

        Console.WriteLine("World!!!");
    }
}

public static void Test<T>() where T : class
{
    Type type = typeof(T);
    type.GetMethods(BindingFlags.Public | BindingFlags.Static)
        .Single(m => m.Name == "Hello")
        .Invoke(null, null);

}     

使用您的示例,我假设您知道接口没有静态方法。我假设你的意思是你有一个接口,它有静态方法的签名,实现所述接口的类只是从实现中调用静态方法。这也可以,但是你不能保证调用正确的静态并确保T对该接口有约束,而不仅仅是new()。

答案 1 :(得分:1)

问题是不能保证T具有名为SomeMethodName的静态成员方法。如果您打算致电AbstractBaseClass.SomeMethodName,请执行此操作。为什么这是不可能的理由是static interface methods讨论的延伸。

答案 2 :(得分:0)

如果不使用反射,就无法做到这一点。要调用静态方法,您始终需要指定实际类型。

如果要提高代码的编译时安全性,可以尝试避免反射。使方法非静态并将其放在接口中。这很可能(我不知道你的问题)是最干净的解决方案。

为了从接口和多态中受益,我做了很多非静态成员。有时我实现类似于单例模式的东西(例如,静态属性来获取实例),或者只是调用默认构造函数来获取实例并将其作为参数传递。

interface ISomeInterface
{
  string SomeMethodName();
}

class SomeImplementation : ISomeInterface
{
  public static Instance { get { return new SomeImplementation(); } }

  public string SomeMethodName()
  {
    // implementation of SomeMethodName
  }
}

public Get(ISomeInterface i)
{
   string s = i.SomeMethodName();
}

public Example()
{
  Get(SomeImplementation.Instance);
}

您也可以在泛型方法中创建新实例,也可以指定需要默认构造函数:

public Get<T>() where T : ISomeInterface, new()
{
   T instance = new T();
   string s = instance.SomeMethodName();
}

public Example()
{
  Get<SomeImplementation>();
}