MakeGenericType()实际上创建了一个对象,我不能使用type's方法

本文关键字:type 方法 不能 实际上 创建 一个对象 MakeGenericType | 更新日期: 2023-09-27 18:16:27

它归结为,我试图使一个泛型,而类型在运行时正确显示,在编译期间,它仍然是object,所以我不能使用任何泛型类型的方法。

感谢无脑编码器在前面的问题上,我能够向前移动一点


dotnetfiddle

using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
    public static void Main()
    {
        var sample = new Baz<List<Foo>>();
        sample.DoSomething();
    }
    public class Foo
    {
    }

    public class Bar<T>
    {
        public void Boom()
        {
        }
    }

    public class Baz<T>
    {
        public void DoSomething(){
            if (typeof(T).Name == "List`1")
            {
                var typeName = typeof(T).GetGenericArguments().Single().FullName;
                var type = Type.GetType(typeName);
                var genericRepoType = typeof(Bar<>);
                var specificRepoType = genericRepoType.MakeGenericType(new Type[] { type });
                var genericBar = Activator.CreateInstance(specificRepoType);
                Console.WriteLine(genericBar.GetType().Name); // Shows Bar`1
                // but at compile time its foo is still an object
                genericBar.Boom(); 
                //will error with 'object' does not contain a definition for Boom
            }
        }
    }
}

MakeGenericType()实际上创建了一个对象,我不能使用type's方法

这听起来像是一个非常有问题的设计,但是如果您必须这样做,dynamic可以很好地解决您的问题。

public static void Main() {
    var sample = new Baz<List<Foo>>();
    sample.DoSomething();
}
public class Foo { }
public class Bar<T> {
    public void Boom() {
        Console.WriteLine("I am booming");
    }
}

public class Baz<T> {
    public void DoSomething() {
        var typeName = typeof(T).GetGenericArguments().Single().FullName;
        var type = Type.GetType(typeName);
        var genericRepoType = typeof(Bar<>);
        var specificRepoType = genericRepoType.MakeGenericType(new Type[] { type });
        dynamic genericBar = Activator.CreateInstance(specificRepoType);
        Console.WriteLine(genericBar.GetType().Name); 
        genericBar.Boom();
    }
}
https://dotnetfiddle.net/uPpfJa

或者,您可以声明一个IBar接口。

public class Bar<T> : IBar {
    public void Boom() {
        Console.WriteLine("I am booming");
    }
}
interface IBar {
    void Boom();
}
...
var genericBar = (IBar)Activator.CreateInstance(specificRepoType);