C# 动态确定类型参数后返回泛型类型

C# 动态确定类型参数后返回泛型类型,c#,generics,C#,Generics,我有一个泛型类,如下所示 public class MyClass<T> { public T MyProp { get; set; } } 公共类MyClass { 公共T MyProp{get;set;} } 现在我想返回这个类型的实例,类型参数在运行时确定,如下所示 public MyClass<object> ReturnWithDynamicParameterType() { //This function determines the ty

我有一个泛型类,如下所示

public class MyClass<T>
{
    public T MyProp { get; set; }
}
公共类MyClass
{
公共T MyProp{get;set;}
}
现在我想返回这个类型的实例,类型参数在运行时确定,如下所示

public MyClass<object> ReturnWithDynamicParameterType()
{
    //This function determines the type of T at runtime and should return instance of MyClass<T>
}
public MyClass ReturnWithDynamicParameterType()返回
{
//此函数在运行时确定T的类型,并应返回MyClass的实例
}

如何做到这一点

你想做的事是不可能的。而您可以像这样在运行时为任意泛型类型参数创建泛型类型

public MyClass<object> ReturnWithDynamicParameterType(Type genericArgument)
{
    Type genericType = typeof(MyClass<>).MakeGenericType(genericArgument);
    return (MyClass<object>)Activator.CreateInstance(genericType);
}
public MyClass ReturnWithDynamicParameterType(类型genericArgument)
{
Type genericType=typeof(MyClass)。MakeGenericType(genericArgument);
return(MyClass)Activator.CreateInstance(genericType);
}
返回
行将始终抛出一个
InvalidCastException
。正如Lee已经指出的,类是不变的。这意味着,例如
MyClass
MyClass
只是不同的类型。他们甚至不是从彼此继承来的

即使协方差也不会有帮助,因为类中的泛型参数不允许使用
out
关键字


如果不知道编译时的类型,我看不到解决方案。但是我相信你可以通过其他方法解决你真正想要实现的问题。

你想要做的是不可能的。而您可以像这样在运行时为任意泛型类型参数创建泛型类型

public MyClass<object> ReturnWithDynamicParameterType(Type genericArgument)
{
    Type genericType = typeof(MyClass<>).MakeGenericType(genericArgument);
    return (MyClass<object>)Activator.CreateInstance(genericType);
}
public MyClass ReturnWithDynamicParameterType(类型genericArgument)
{
Type genericType=typeof(MyClass)。MakeGenericType(genericArgument);
return(MyClass)Activator.CreateInstance(genericType);
}
返回
行将始终抛出一个
InvalidCastException
。正如Lee已经指出的,类是不变的。这意味着,例如
MyClass
MyClass
只是不同的类型。他们甚至不是从彼此继承来的

即使协方差也不会有帮助,因为类中的泛型参数不允许使用
out
关键字


如果不知道编译时的类型,我看不到解决方案。但是我相信你可以通过其他方法来解决你实际想要实现的问题。

我不确定这是否适合你的使用,但你唯一的出路是使用协变的接口

public interface IMyClass<out T>
{
    T MyProp { get; }
}

public class MyClass<T> : IMyClass<T>
{
    public T MyProp { get; set; }
}

public IMyClass<object> ReturnWithDynamicParameterType()
{
    //This function determines the type of T at runtime and should return instance of MyClass<T>

    return new MyClass<string>();
}
公共接口IMyClass
{
T MyProp{get;}
}
公共类MyClass:IMyClass
{
公共T MyProp{get;set;}
}
public IMyClass ReturnWithDynamicParameterType()
{
//此函数在运行时确定T的类型,并应返回MyClass的实例
返回新的MyClass();
}

之所以编译此代码,是因为您的返回类型不是类,而是协变接口(请注意type参数上的
out T
)。该接口只允许检索,因此
get;属性上的set
已被界面上的get替换。

我不确定这是否适合您的使用,但您唯一的出路是使用协变界面

public interface IMyClass<out T>
{
    T MyProp { get; }
}

public class MyClass<T> : IMyClass<T>
{
    public T MyProp { get; set; }
}

public IMyClass<object> ReturnWithDynamicParameterType()
{
    //This function determines the type of T at runtime and should return instance of MyClass<T>

    return new MyClass<string>();
}
公共接口IMyClass
{
T MyProp{get;}
}
公共类MyClass:IMyClass
{
公共T MyProp{get;set;}
}
public IMyClass ReturnWithDynamicParameterType()
{
//此函数在运行时确定T的类型,并应返回MyClass的实例
返回新的MyClass();
}

之所以编译此代码,是因为您的返回类型不是类,而是协变接口(请注意type参数上的
out T
)。该接口只允许检索,因此
get;属性上的set
已被界面上的get替换。

请描述您想要实现的目标-真正的问题。类是不变的,因此您无法将
MyClass
作为
MyClass
返回。即使是这样,
MyProp
上的setter也会阻止
MyClass
T
中是协变的。除了返回类型不正确之外,你不能,除非你有一个T可能是协变的类型的确定列表。每个特定的MyClass都是在编译时生成的。因此,您需要在ReturnWithDynamicParameterType()方法中创建列表。请描述您想要实现的目标-真正的问题。类是不变的,因此您无法将
MyClass
作为
MyClass
返回。即使是这样,
MyProp
上的setter也会阻止
MyClass
T
中是协变的。除了返回类型不正确之外,你不能,除非你有一个T可能是协变的类型的确定列表。每个特定的MyClass都是在编译时生成的。因此,您需要在ReturnWithDynamicParameterType()方法中创建列表。对,我也尝试过,但没有将其包含在我的答案中,因为您无法在接口中声明setter(因为它需要相反的变量)+1无论如何,这是接近要求的唯一方法。对,我也尝试过,但没有将其包含在我的答案中,因为您无法在接口中声明setter(因为它需要相反的变量)+1无论如何,这是接近要求的唯一途径。