Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从动态类型创建泛型类的实例_C#_.net_Generics_Reflection - Fatal编程技术网

C# 从动态类型创建泛型类的实例

C# 从动态类型创建泛型类的实例,c#,.net,generics,reflection,C#,.net,Generics,Reflection,是否可以创建类型为动态派生的泛型类的实例 Class泛型类{ } Main() { 字符串inputtype=“classname,assemblyname”; Type Type=Type.GetType(inputtype); 动态实例=Activator.CreateInstance(类型); //想要创建GenericClass的对象,但我收到compiletime错误。 //有可能像下面这样做吗? GenericClass=新的GenericClass(); } 您可以像这样使用反射:

是否可以创建类型为动态派生的泛型类的实例

Class泛型类{
}
Main()
{
字符串inputtype=“classname,assemblyname”;
Type Type=Type.GetType(inputtype);
动态实例=Activator.CreateInstance(类型);
//想要创建GenericClass的对象,但我收到compiletime错误。
//有可能像下面这样做吗?
GenericClass=新的GenericClass();
}

您可以像这样使用反射:

对象genericInstance=Activator.CreateInstance(typeof(GenericClass).MakeGenericType(type));
但是,您必须强制转换它以使用它,因此它不是类型安全的。

是的,您可以在运行时实例化泛型类型,知道它需要的泛型类型参数。你能用它做些有用的事吗?那要看情况

这里有一个例子。请注意,我有一个(非通用)接口,它提供了我可以使用的行为:

public class Program
{
    public static void Main(string[] args)
    {

        var genericType = typeof(int); // You could have a string and Type.GetType here
        var genericClassType = typeof(GenericClass<>).MakeGenericType(genericType);
        var instance = (ICanTellYouMyType)Activator.CreateInstance(genericClassType);
        Console.WriteLine(instance.WhatsMyGenericType()); 
        // Output is "Int32"

    }
}

public interface ICanTellYouMyType
{
    string WhatsMyGenericType();
}

public class GenericClass<T> : ICanTellYouMyType
{
    public string WhatsMyGenericType()
    {
        return typeof(T).Name;
    }
}
公共类程序
{
公共静态void Main(字符串[]args)
{
var genericType=typeof(int);//这里可以有一个字符串和Type.GetType
var genericClassType=typeof(GenericClass)。MakeGenericType(genericType);
var instance=(ICanTellYouMyType)Activator.CreateInstance(genericClassType);
WriteLine(instance.WhatsMyGenericType());
//输出为“Int32”
}
}
公共接口ICanTellYouMyType
{
字符串WhatsMyGenericType();
}
公共类GenericClass:ICanTellYouMyType
{
公共字符串WhatsMyGenericType()
{
返回typeof(T).Name;
}
}

实例:

其他答案实际上并没有回答您的问题,即:

我可以这样做吗:
GenericClass=newgenericClass()

不,你不能。正如其他答案所解释的,您可以创建一个泛型对象,其类型只有在运行时通过反射才能知道,但您不能利用刚刚在编译时创建的对象的任何类型信息

?如果只在运行时知道,你怎么会知道?如果它不仅在运行时被知道,那么你就不会一开始就陷入这样的混乱;您应该在编译时指定一个可分配的类型(在代码中)

仿制药,在这里是一个危险的话题。您的问题基本上是在编写代码时不知道对象的类型:

Type t = someMethodGivesMeATypeIDontKnowWhenWritingThisCode();

//I need to make an instance of this type.
//The only thing I know is that it needs to have a default contructor
//or it will crash
var o = Activator.CreateInstance(t);

你认为
o
的编译时间是多少?它只能是
对象
,因为编译器不知道也不可能知道关于对象的真实类型的任何信息。

是的,可以使用反射。但一般来说,如果您在编译时不知道泛型类型,则可能是使用泛型错误,或者根本不需要泛型。由于
MakeGenericType
使用
params type[]
可以执行
MakeGenericType(type)
。我现在可以创建实例,但是现在无法访问公共方法除非您将对象强制转换为公开公共方法的对象,否则它们将无法访问-cf Jamiec回答了这一点。我可以使用反射动态调用公共方法吗?是的,请查看。如果没有您提供更多的上下文,这看起来像是一个狡猾的举动。我现在可以创建实例,但现在无法访问公共方法。@phanish这是我关于这样做是否有用的观点。如果不强制转换该对象,您就无法访问该对象,除非您知道它们在编译时键入-除非根据我的回答,您有一个公共接口。我是否可以使用反射动态调用公共方法?@phanish Yes,如果您知道要调用的方法的签名。您还可以使用dynamic,使代码更易于编写/读取。