gpt4 book ai didi

c# - 如何在 C# 中获取泛型类的子类型

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

我有一个通用方法

public async Task Save<T>(T aggregate) where T : AggregateRoot

从这个方法我调用另一个泛型方法

var indexRegistrations = IndexRegistrar.GetAll<T>();

现在在第二个泛型方法中,我想获取 T 的真实类型,它是 AggregateRoot 的子类型:

public static List<IndexRegistration> GetAll<T>() where T : AggregateRoot
{
return _register.FindAll(r => r.aggregateType == typeof(T));
}

但是,typeof(T) 总是返回 AggregateRoot

如何获取 T 的真实类型(=AggregateRoot 的子类型)?

最佳答案

typeof(T) 在这里是正确的。

我测试了你的情况,typeof(T) 总是返回“true”类,而不仅仅是类型要求。

public class BaseClass { }
public class DerivedClass: BaseClass { }

public class GenericClass<T> where T : BaseClass
{
public string TypeOf = typeof(T).ToString();
}

public class GenericSuperClass<T> where T : BaseClass
{
public GenericClass<T> Sub = new GenericClass<T>();
}

static void Main(string[] args)
{
Console.WriteLine("1 - " + (new GenericClass<BaseClass>()).TypeOf);
Console.WriteLine("2 - " + (new GenericClass<DerivedClass>()).TypeOf);

Console.WriteLine("3 - " + (new GenericSuperClass<BaseClass>()).Sub.TypeOf);
Console.WriteLine("4 - " + (new GenericSuperClass<DerivedClass>()).Sub.TypeOf);

Console.ReadLine();
}

输出:

1 - BaseClass
2 - DerivedClass
3 - BaseClass
4 - DerivedClass

请注意,我已经从实际返回的值中简化了类名(例如 Sandbox.TestConsole.Program+DerivedClass)。

这直接与您声称您只能获得基本类型(AggregateRoot,在您的情况下)的说法相矛盾。


反射是一个异常(exception)。

我能想到一个异常(exception):当您的类型仅在运行时 定义时(例如,从类型名称 (String) 生成)。
然而,作为this StackOverflow answer解释说,泛型旨在提供编译时类型安全。

在运行时使用反射来实例化泛型类并非不可能。但是当你这样做时,你本质上是在阻止在编译时决定的信息(例如类型名称)的有效性。
MSDN's page on typeof隐式声明 typeof 的返回值是编译时类型。

结合这两个事实,这意味着当您使用反射(即在运行时决定类型)时,您不能依赖typeof(因为这会返回编译时间类型)。


链接的 MSDN 页面还提到了如何找到运行时类型:

To obtain the run-time type of an expression, you can use the .NET Framework method GetType, as in the following example:

int i = 0;
System.Type type = i.GetType();

但是请注意,GetType() 方法仅适用于实例化 对象,不适用于泛型类型参数。泛型类型参数并不是真正的类型,它们更接近于“类型占位符”。

您需要将类型作为参数传递,或者传递实例化对象(适当类型)。


结论:

如果您使用的是编译时已知的类型,那么您可以简单地使用 typeof(T),如我的示例所示。

如果您使用反射在运行时决定类型,那么您不能依赖 typeof(T) 提供的信息,因此需要提供类型。要么将其作为 Type 参数提供,要么通过实例化对象提供,其运行时类型可以使用 GetType() 进行准确测试> 方法。

但是,如果您已经在运行时决定了类型,那么您最好将类型本身作为参数传递。如果您在此处使用反射,则意味着您必须在某个时候知道要使用哪种类型。因此,只需将该已知类型作为参数传递,然后您就可以将其用于后续业务逻辑。

我想不出有哪个场景是您既 (a) 使用编译时已知的类型,也 (b) 不知道(在运行时)您决定使用的类型。

关于c# - 如何在 C# 中获取泛型类的子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46151195/

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