如何在 AOT 平台上在运行时生成任何泛型类型?
How can I generate any generic type at runtime on AOT platforms?
我需要在 AOT 平台上运行时生成泛型类型。我知道一个 "workaround" 提示编译器通过在代码中创建一个虚拟方法来生成特定的泛型 class:
public void DoDummy(){
var a1 = new MyClass<MyType>();
}
不幸的是,这个特定的解决方法对我不起作用,因为我可以创建超过几十万(毫不夸张)的类型组合。
有什么方法可以实现我想要实现的目标吗?
我不是 100% 确定我理解你想做什么,但也许这对你有帮助:
private static object Create(Type genericType, params Type[] genericArguments)
{
Type genericClass = genericType.MakeGenericType(genericArguments);
return Activator.CreateInstance(genericClass);
}
此方法为您要创建的 genericType
创建所有需要的泛型类型参数,并使用其无参数构造函数创建结果类型的实例。
如果你class喜欢
public class MyClass<T>
{
}
并想用 string
作为类型参数实例化它,你可以这样称呼它:
var myinstance = Create(typeof(MyClass<>), typeof(string));
请注意,如果您想有效地使用 return 值 (myinstance
),您应该将其声明为 dynamic
。
虽然不是完美的解决方案,但我发现可以使用通用接口和通用抽象 class.
创建一个通用的 class,例如:
public abstract class GenericBase<T>
{
public static bool AOTConstruct()
{
bool b = (new GV<T>() == null); // Where GV<T> is a Generic Class.
// Do similar for all Generic Classes that need to be AOT compiled.
return b;
}
}
然后创建一个通用接口,例如:
public interface IGenericValue<T>
{
GenericBase<T> ConstructGenericBase();
}
现在,系统类型可以为 AOTConstruct 中列出的通用 classes 进行 AOT 编译,方法是声明为实现接口的 class 类型,如下所示:
public class SystemTypes : IGenericValue<float> // Implement IGenericValue for other Types.
{
GenericBase<float> IGenericValue<float>.ConstructGenericBase()
{
throw new NotImplementedException();
}
}
同样可以对任何自定义 class 执行相同的操作,或者在与系统类型相同的 class 中,或者作为自定义 class' 声明的一部分(我更喜欢为了清楚起见)。
令人失望的是必须更新 SystemTypes 以支持新的系统级类型,并更新需要支持的新泛型 类 的 AOTConstruct,但它适用于编译为 iOS 并且不需要列出所有组合。
我需要在 AOT 平台上运行时生成泛型类型。我知道一个 "workaround" 提示编译器通过在代码中创建一个虚拟方法来生成特定的泛型 class:
public void DoDummy(){
var a1 = new MyClass<MyType>();
}
不幸的是,这个特定的解决方法对我不起作用,因为我可以创建超过几十万(毫不夸张)的类型组合。
有什么方法可以实现我想要实现的目标吗?
我不是 100% 确定我理解你想做什么,但也许这对你有帮助:
private static object Create(Type genericType, params Type[] genericArguments)
{
Type genericClass = genericType.MakeGenericType(genericArguments);
return Activator.CreateInstance(genericClass);
}
此方法为您要创建的 genericType
创建所有需要的泛型类型参数,并使用其无参数构造函数创建结果类型的实例。
如果你class喜欢
public class MyClass<T>
{
}
并想用 string
作为类型参数实例化它,你可以这样称呼它:
var myinstance = Create(typeof(MyClass<>), typeof(string));
请注意,如果您想有效地使用 return 值 (myinstance
),您应该将其声明为 dynamic
。
虽然不是完美的解决方案,但我发现可以使用通用接口和通用抽象 class.
创建一个通用的 class,例如:
public abstract class GenericBase<T>
{
public static bool AOTConstruct()
{
bool b = (new GV<T>() == null); // Where GV<T> is a Generic Class.
// Do similar for all Generic Classes that need to be AOT compiled.
return b;
}
}
然后创建一个通用接口,例如:
public interface IGenericValue<T>
{
GenericBase<T> ConstructGenericBase();
}
现在,系统类型可以为 AOTConstruct 中列出的通用 classes 进行 AOT 编译,方法是声明为实现接口的 class 类型,如下所示:
public class SystemTypes : IGenericValue<float> // Implement IGenericValue for other Types.
{
GenericBase<float> IGenericValue<float>.ConstructGenericBase()
{
throw new NotImplementedException();
}
}
同样可以对任何自定义 class 执行相同的操作,或者在与系统类型相同的 class 中,或者作为自定义 class' 声明的一部分(我更喜欢为了清楚起见)。
令人失望的是必须更新 SystemTypes 以支持新的系统级类型,并更新需要支持的新泛型 类 的 AOTConstruct,但它适用于编译为 iOS 并且不需要列出所有组合。