Calling static member when you have only generic parameter

折月煮酒 提交于 2020-01-30 07:39:48

问题


Ts there any way to call a static member on type when I only have a generic parameter. For example if I have something like this

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

I could do it like this but is kinda "yucky", and then it does not matter if it is static or not. Or I could use reflection as suggested by Yuriy.

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

So question is now which is better approach, creating new instance of using reflection

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);

回答1:


Wouldn't that just always be AbstractBaseClass.GetFullName(). Otherwise you have to use reflection on T to get the static method of another class. This might be helpful.

The following is a simple example:

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);

}     

With your sample, I assume you know interfaces don't have static methods. I assumed you meant you had an interface which has a signature for the static method and a class implementing said interface would just call the static method from the implementation. That would work as well, but you're not guaranteed the correct static will be called and make sure T has a constraint on that interface, not just new().




回答2:


The problem is there's no guarantee that T has a static member method named SomeMethodName. If you mean to call AbstractBaseClass.SomeMethodName, then do so. The rationale for why this is impossible is an extension of the static interface methods discussion.




回答3:


There is no way to do this without using reflection. To call a static method, you always need to specify the actual type.

If you want to improve the compile-time safety of your code, you would try to avoid reflection. Make the method non-static and put it in an interface. This would most probably (I don't know your problem) be the cleanest solution.

I made quite a few members non-static just to benefit from interfaces and polymorphism. Sometimes I implement something similar to the singleton pattern (eg. static property to get an instance), or just call the default constructor to get an instance and and pass it as argument.

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);
}

You may also create the new instance in the generic method, you can also specify that you need a default constructor:

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

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


来源:https://stackoverflow.com/questions/1534869/calling-static-member-when-you-have-only-generic-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!