Reflection and generic types

后端 未结 3 1474
借酒劲吻你
借酒劲吻你 2020-12-05 05:48

I\'m writing some code for a class constructor which loops through all the properties of the class and calls a generic static method which populates my class with data from

相关标签:
3条回答
  • 2020-12-05 06:11

    Do you want to call DoStuff<T> with T = the type of each property? In which case, "as is" you would need to use reflection and MakeGenericMethod - i.e.

    var properties = this.GetType().GetProperties();
    foreach (PropertyInfo p in properties)
    {
        object value = typeof(MyClass)
        .GetMethod("DoStuff")
        .MakeGenericMethod(p.PropertyType)
        .Invoke(null, new object[] { p.Name });
        p.SetValue(this, value, null);
    }
    

    However, this isn't very pretty. In reality I wonder if it wouldn't be better just to have:

    static object DoStuff(string name, Type propertyType);
    ... and then
    object value = DoStuff(p.Name, p.PropertyType);
    

    What does the generics give you in this example? Note that value-types will still get boxed etc during the reflection call - and even then boxing isn't as bad as you might think.

    Finally, in many scenarios, TypeDescriptor.GetProperties() is more appropriate than Type.GetProperties() - allows for flexible object models etc.

    0 讨论(0)
  • 2020-12-05 06:19

    If you don't use DoStuff from another place, I also suggest to write a non-generic method.

    Maybe you created the generic method to be able to use default(T). To replace that in a non-generic method, you can use Activator.CreateInstance(T) for value types and null for reference types:

    object defaultResult = type.IsValueType ? Activator.CreateInstance(type) : null
    
    0 讨论(0)
  • 2020-12-05 06:23

    Was your constructor code meant to read like this:

    public MyClass(){
      var properties = this.GetType().GetProperties();
      foreach(PropertyInfo p in properties){
        p.SetValue(this, DoStuff(p.Name), new object[0]);
      }
    }
    

    ? Note the DoStuff instead of MyClass.

    If so, the problem is that you're trying to use generics when they're really not applicable. The point of generics (well, one of the points) is to use compile-time type safety. Here you don't know the type at compile time! You could call the method by reflection (fetching the open form and then calling MakeGenericMethod) but that's pretty ugly.

    Does DoStuff really need to be generic in the first place? Is it being used from elsewhere? The parameter to PropertyInfo.SetValue is just object, so you'd still get boxing etc even if you could call the method generically.

    0 讨论(0)
提交回复
热议问题