【问题标题】:Passing an instance of a dynamic type to a generic method in a generic class将动态类型的实例传递给泛型类中的泛型方法
【发布时间】:2017-12-23 01:56:28
【问题描述】:

我有一个公开泛型方法的泛型类。该方法接收一个泛型对象的实例作为参数并修改该实例。

示例类:

public class GenericClass<T>
{
    public T GenericMethod(T obj)
    {
        // modify the object in some (arbitrary) way
        IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
        foreach (FieldInfo field in fields)
        {
            if (field.FieldType == typeof(string))
            {
                field.SetValue(obj, "This field's string value was modified");
            }
        }

        return obj;
    }
}

如果我有一个类型(abc):

public class abc
{
    public string a;
    public string b;
    public int c;
}

我可以这样调用这个方法:

GenericClass<abc> myGeneric = new GenericClass<abc>();
var myObject = myGeneric.GenericMethod(new abc());

//Confirm success by printing one of the fields
Console.Writeline(((abc)myObject).a);

现在,我的实际问题:

我将如何使用仅在运行时已知的类型(与上面的 abc 类型相反)调用相同的通用方法。我还想在将它传递给 GenericMethod 时实例化它,就像我为上面的 abc 所做的那样。

例如(我知道这是完全错误的)

Type MyType;

GenericClass<MyType> myGeneric = new GenericClass<MyType>();
var myObject = myGeneric.GenericMethod(new MyType());

由于未知类型的成功无法通过打印可能不存在的字段“a”来确认,我可以打印所有字符串字段的值,但这超出了问题的范围。

【问题讨论】:

  • 你真的需要让它通用吗?因为在您提供的示例中,您也可以将方法声明为public void GenericMethod(object obj)
  • @Evk 敏锐的观察,谢谢。有时,如果有人帮助您退后一步,这会有所帮助。

标签: c# generics dynamic reflection runtime


【解决方案1】:

回答你的问题:

var type = typeof(abc);
object instanceToModify = new abc();

var typeToCreate = typeof(GenericClass<>).MakeGenericType(type);
var methodToCall = typeToCreate.GetMethod("GenericMethod");

var genericClassInstance = Activator.CreateInstance(typeToCreate);
methodToCall.Invoke(genericClassInstance, new[] { instanceToModify });

DEMO

但是:

如果您的类型仅在运行时已知,您的实例必须在声明为objectdynamic 的变量中处理。在这种情况下,您可以将方法签名更改为:

public object GenericMethod(object obj)
{
    // modify the object in some (arbitrary) way
    IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
    foreach (var field in fields)
    {
        if (field.FieldType == typeof(string))
        {
            field.SetValue(obj, "This field's string value was modified");
        }
    }

    return obj;
}

不需要泛型类/方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    相关资源
    最近更新 更多