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
)的说法相矛盾。
反射是一个例外。
我可以想到一个例外:当您的类型只在运行时定义时(例如从类型名称(String
)生成),就会出现这种情况。
但正如这个StackOverflow答案所解释的那样,泛型旨在提供编译时类型安全性。
使用反射在运行时实例化泛型类并不是不可能。但是当您这样做时,您本质上正在阻止在编译时确定的信息(例如类型名称)的有效性。
MSDN关于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)在运行时了解您决定使用的类型。
GetType
。任何其他调用,如typeof(T)
,都会返回编译时类型,这在你的情况下是无关紧要的。 - mrogal.skiSave()
方法之前将对象强制转换为**AggregateRoot
**。因此 T == AggregateRoot。 - Peter BGetAll(Type searchType)
是否可行?这样您就可以传递运行时类型... - Fildor