MakeGenericType()实际上是一个对象,我不能使用类型的方法

时间:2015-10-07 22:05:13

标签: c# generics

它归结为我尝试制作Generic并且类型在运行时正确显示,在编译期间它仍然是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
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这听起来像是一个非常值得怀疑的设计,但如果必须,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);