gpt4 book ai didi

c# - 通用类型用作更具体的通用类型

转载 作者:太空宇宙 更新时间:2023-11-03 21:07:44 25 4
gpt4 key购买 nike

我有 Class1 和通用 T1,Class2 和通用 T2。通用 T2 有约束,而 T1 没有。

现在在 Class1 中,我想检查 T1 是否与 T2 的约束相匹配,以及它是否与 Class2 一起使用。

这可能吗?怎么办?

public class Class1<T1> {
public static object GetObj() {
if (typeof(SomeBaseClass).IsAssignableFrom(typeof(T1))) {
// I know that T1 is a subclass of SomeBaseClass, and want to create a Class2 object using it
return new Class2<T1>(); // this doesn't work. How can I "force" the compiler to treat T1 as a T2, like casting?
}
}
}

public class Class2<T2> where T2 : SomeBaseClass {
}

编辑:不幸的是,由于开销,反射不是一个好的解决方案,这被调用了很多。

最佳答案

正如@AakashM 所说,我想使用反射是唯一的方法:

public class Class1<T1>
{
public static object GetObj()
{
if (typeof(SomeBaseClass).IsAssignableFrom(typeof(T1)))
{
var genericType = typeof(Class2<>).MakeGenericType(typeof(T1));
return Activator.CreateInstance(genericType);
}

// throw Exception or return null
}
}

更新

根据您的评论,如果反射太慢,您可以使用编译表达式:

public class Class1<T1>
{
private static readonly Func<T1> _factory;

static Class1()
{
if (!typeof(SomeBaseClass).IsAssignableFrom(typeof(T1)))
{
_factory = () => default(T1);
return;
}

var ctor = typeof(T1).GetConstructor(Array.Empty<Type>());
var newExpression = Expression.New(ctor);

_factory = Expression.Lambda<Func<T1>>(newExpression).Compile();
}

public static object GetObj()
{
return _factory();
}
}

此解决方案为 Class1 的每个变体创建一个工厂(例如 Class1<SomeSubClass>Class1<SomeOtherSubClass> 等)。构建表达式需要一些时间,但之后速度非常快。

我已经运行了一些测试来查看创建 100 万个 Class2 实例需要多长时间使用 GetObj()方法:

  • 最佳情况(约束添加到 Class1 ,只需返回 new Class2<T1>() ):4 毫秒
  • 反射(如原解所示):991 ms
  • 使用编译表达式(如上所示):26 毫秒

如您所见,新解决方案比以前的解决方案快得多。但是,如果您为 T1 使用了很多不同的类型性能提升会更小甚至不存在。

关于c# - 通用类型用作更具体的通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40108632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com