C#泛型的类型检查
假设我有一节课C#泛型的类型检查,c#,generics,typechecking,C#,Generics,Typechecking,假设我有一节课 public class Entity<T> { ... // class definition ... } 可以将变量的泛型类型定义与实体类的泛型类型定义进行比较 Type genericType = typeof(Entity<>); var a = new Entity<string>(); bool isAOfTypeEntity = a.GetType().IsGenericType && a.G
public class Entity<T> { ... // class definition ... }
可以将变量的泛型类型定义与实体类的泛型类型定义进行比较
Type genericType = typeof(Entity<>);
var a = new Entity<string>();
bool isAOfTypeEntity =
a.GetType().IsGenericType &&
a.GetType().GetGenericTypeDefinition() == genericType;
// returns true.
Type genericType=typeof(实体);
var a=新实体();
布尔型实体=
a、 GetType().IsGenericType&&
a、 GetType().GetGenericTypeDefinition()==genericType;
//返回true。
请注意,我们首先使用IsGenericType进行检查,否则GetGenericTypeDefinition将抛出错误
请先检查null。我认为,您可以将所有这些重构为一种方法
可以有更快或更好的方法,如果提供的话,我会很高兴看到它们
希望这能有所帮助。如果您在检查泛型类型是否为实体时不关心它,可以添加一个额外的类
public class Entity { } // If you want, you can make it abstract.
public class Entity<T> : Entity { ... // class definition ... }
var a = new Entity<string>();
var b = new Entity<int>();
var c = new Entity<bool>();
var d = new int;
var e = new List<string>();
a is Entity // true
b is Entity // true
c is Entity // true
d is Entity // false
e is Entity // false
公共类实体{}//如果需要,可以将其抽象化。
公共类实体:实体{…//类定义…}
var a=新实体();
var b=新实体();
var c=新实体();
var d=新整数;
var e=新列表();
实体//为真
b是真的吗
c是实体//真的吗
d是实体//false
e是实体//假
如果您所处的环境不太关心性能,那么反射可以成为您的解决方案。但是,我建议不要使用反射,而是让实体
继承自非泛型类型的实体
或实体
(参见Silvermind的答案)
对于反射,这些扩展方法应该允许您检查typeof(Entity)
(可选的布尔参数默认也检查基本类型):
IsInstanceOfGenericType
方法可以这样使用:
class InheritingClass : Entity<string> { }
class Entity<T> : IEntity<T> { }
interface IEntity<T> { }
这项工作:
public class Entity<T>
{
}
static class Program
{
static void Main(string[] args)
{
var a = new Entity<string>();
var b = new Entity<int>();
var c = new Entity<Point>();
var e = 1001;
var f = new List<int>();
if (a.IsEntity())
{
Debug.WriteLine($"{nameof(a)} is an Entity");
}
if (b.IsEntity())
{
Debug.WriteLine($"{nameof(b)} is an Entity");
}
if (c.IsEntity())
{
Debug.WriteLine($"{nameof(c)} is an Entity");
}
if (e.IsEntity())
{
Debug.WriteLine($"{nameof(e)} is an Entity");
}
if (f.IsEntity())
{
Debug.WriteLine($"{nameof(f)} is an Entity");
}
}
static bool IsEntity(this object obj)
{
var t = obj.GetType();
if (t.IsGenericType)
{
return typeof(Entity<>).IsAssignableFrom(t.GetGenericTypeDefinition());
}
return false;
}
}
公共类实体
{
}
静态类程序
{
静态void Main(字符串[]参数)
{
var a=新实体();
var b=新实体();
var c=新实体();
var e=1001;
var f=新列表();
if(a.IsEntity())
{
WriteLine($“{nameof(a)}是一个实体”);
}
if(b.IsEntity())
{
WriteLine($“{nameof(b)}是一个实体”);
}
if(c.IsEntity())
{
WriteLine($“{nameof(c)}是一个实体”);
}
if(例如,IsEntity())
{
WriteLine($“{nameof(e)}是一个实体”);
}
if(f.IsEntity())
{
WriteLine($“{nameof(f)}是一个实体”);
}
}
静态对象实体(此对象对象对象)
{
var t=obj.GetType();
if(t.IsGenericType)
{
返回typeof(Entity).IsAssignableFrom(t.GetGenericTypeDefinition());
}
返回false;
}
}
好奇心;使用反射会在多大程度上影响性能?怎么会这样?另外,谢谢你的解决方案,我可以试试。非常感谢!现在一切正常。
static bool IsInstanceOfGenericType(this object item, Type @type, bool includeBaseTypes = true) {
return item.GetType().IsBasedOnGenericType(@type, includeBaseTypes);
}
static bool IsBasedOnGenericType(this Type t, Type @type, bool includeBaseTypes = true) {
return (t.IsGenericType && t.GetGenericTypeDefinition() == @type)
|| includeBaseTypes
&& (t.GetInterfaces().Any(i => IsBasedOnGenericType(i, @type))
|| (t.BaseType != null ? IsBasedOnGenericType(t.BaseType, @type) : false));
}
class InheritingClass : Entity<string> { }
class Entity<T> : IEntity<T> { }
interface IEntity<T> { }
var item = new InheritingClass();
var item2 = new Entity<string>();
var item3 = new Entity<string>();
var item4 = new List<string>();
var item5 = new InheritingClass();
Console.WriteLine( "item: " + item.IsInstanceOfGenericType(typeof(Entity<>)) );
Console.WriteLine( "item2: " + item2.IsInstanceOfGenericType(typeof(Entity<>)) );
Console.WriteLine( "item3: " + item3.IsInstanceOfGenericType(typeof(IEntity<>)) );
Console.WriteLine( "item4: " + item4.IsInstanceOfGenericType(typeof(IEntity<>)) );
Console.WriteLine( "item5: " + item5.IsInstanceOfGenericType(typeof(Entity<>), false) );
item: True
item2: True
item3: True
item4: False
item5: False
public class Entity<T>
{
}
static class Program
{
static void Main(string[] args)
{
var a = new Entity<string>();
var b = new Entity<int>();
var c = new Entity<Point>();
var e = 1001;
var f = new List<int>();
if (a.IsEntity())
{
Debug.WriteLine($"{nameof(a)} is an Entity");
}
if (b.IsEntity())
{
Debug.WriteLine($"{nameof(b)} is an Entity");
}
if (c.IsEntity())
{
Debug.WriteLine($"{nameof(c)} is an Entity");
}
if (e.IsEntity())
{
Debug.WriteLine($"{nameof(e)} is an Entity");
}
if (f.IsEntity())
{
Debug.WriteLine($"{nameof(f)} is an Entity");
}
}
static bool IsEntity(this object obj)
{
var t = obj.GetType();
if (t.IsGenericType)
{
return typeof(Entity<>).IsAssignableFrom(t.GetGenericTypeDefinition());
}
return false;
}
}