[英]C# Type comparison using reflection
我想使用反射检查属性是否属于DbSet<T>
类型。
public class Foo
{
public DbSet<Bar> Bars { get; set; }
}
通过使用反射:
var types = Assembly.GetExecutingAssembly().GetTypes();
foreach (var type in types)
{
if (type.IsSubclassOf(typeof (Foo)) || type.FullName == typeof (Foo).FullName)
{
foreach (
var prop in Type.GetType(type.FullName).
GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
{
var propType = prop.PropertyType;
bool a = propType.IsAssignableFrom(typeof (DbSet<>));
bool b = typeof (DbSet<>).IsAssignableFrom(propType);
bool c = propType.BaseType.IsAssignableFrom(typeof (DbSet<>));
bool d = typeof (DbSet<>).IsAssignableFrom(propType.BaseType);
bool e = typeof (DbSet<>).IsSubclassOf(propType);
bool f = typeof (DbSet<>).IsSubclassOf(propType.BaseType);
bool g = propType.IsSubclassOf(typeof (DbSet<>));
bool h = propType.BaseType.IsSubclassOf(typeof (DbSet<>));
bool i = propType.BaseType.Equals(typeof (DbSet<>));
bool j = typeof (DbSet<>).Equals(propType.BaseType);
bool k = propType.Name == typeof (DbSet<>).Name;
}
}
}
是否有合并的解决方案来检查类型? 如您所见,我正在使用IsSubClassOf
+ FullName
来获取Foo
类型的类和从Foo
派生的任何其他类。
除了 c,f,k 之外的所有检查(a 到 j)都返回 false。 c,f 将 System.Object 作为 BaseType 返回,这对我没有用。 k,我认为是不安全的检查。 但如果没有找到其他解决方法,我将使用我的方法。 在调试模式下, propType
的FullName
是:
System.Data.Entity.DbSet`1[[Console1.Bar, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
有没有其他方法可以检查propType
是否属于DbSet<>
类型?
谢谢。
您是否也需要它来处理DbSet<>
子类? 如果没有,您可以使用:
if (propType.IsGenericType &&
propType.GetGenericTypeDefinition() == typeof(DbSet<>))
完整样本:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
class Test<T>
{
public List<int> ListInt32 { get; set; }
public List<T> ListT { get; set; }
public string Other { get; set; }
public Action<string> OtherGeneric { get; set; }
}
class Program
{
static void Main(string[] args)
{
var query = from prop in typeof(Test<string>).GetProperties()
let propType = prop.PropertyType
where propType.IsGenericType &&
propType.GetGenericTypeDefinition() == typeof(List<>)
select prop.Name;
foreach (string name in query)
{
Console.WriteLine(name);
}
}
}
对于子类,您只需要在继承层次结构中递归地应用相同的测试。 如果您需要测试接口,这将变得更加痛苦。
您的代码的问题在于它假设typeof(DbType<>)
表示常规类型。 它不是一个普通类型:相反,它是一个泛型类型定义。 这就是IsAssignableFrom
、 IsSubclassOf
等不起作用的原因。 如果以下条件为真,则Type
x
的类型为DbSet<T>
:
x.IsGenericType && x.GetGenericTypeDefinition() == typeof(DbSet<>) && x.GetGenericTypeArguments()[0] == typeof(T)
我建议进行以下类型比较(对我来说很好用):
foreach (var prop in customObject.GetType().GetProperties().Where(e => e.CanRead && e.CanWrite))
{
var typeName = prop.PropertyType.FullName ?? "";
//!!! Type comparision here:
if (typeName == typeof(string).FullName)
{
prop.SetValue(customObject, "abc");
continue;
}
// other code
}
对于可为空的类型(例如DateTime?
),您可以使用这种类型的比较:
if (typeName.Contains(typeof(string).FullName))
{
prop.SetValue(customObject, "abc");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.