I'd like to check if a property is of type DbSet<T>
using reflection.
public class Foo
{
public DbSet<Bar> Bars { get; set; }
}
By using reflection:
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;
}
}
}
Is there a merged solution to check the type? As you can see, I'm using IsSubClassOf
+ FullName
to get classes of type Foo
and any other class which is derived from Foo
.
all the checks (a to j) except c,f,k return false. c,f return System.Object as BaseType which is no use for me. k, I consider an unsafe check . But will be my what I use if no other workaround is found. In debug mode, the propType
's FullName
is:
System.Data.Entity.DbSet`1[[Console1.Bar, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
Is there any other way to check if propType
is of type DbSet<>
?
Thanks.
Do you need it to cope with subclasses of DbSet<>
as well? If not, you can use:
if (propType.IsGenericType &&
propType.GetGenericTypeDefinition() == typeof(DbSet<>))
Full sample:
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);
}
}
}
With subclasses you'd just need to apply the same test recursively up the inheritance hierarchy. It becomes more of a pain if you need to test for interfaces.
The problem with your code is that it is assuming that typeof(DbType<>)
denotes a regular type. It is not a normal type: rather, it is a generic type definition. That is why the IsAssignableFrom
, IsSubclassOf
etc. are not going to work. Type
x
is of type DbSet<T>
if the following condition is true:
x.IsGenericType && x.GetGenericTypeDefinition() == typeof(DbSet<>) && x.GetGenericTypeArguments()[0] == typeof(T)
I'd suggest the following type comparision (worked fine for me):
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
}
For nullable types (for example DateTime?
) you might use this type of comparison:
if (typeName.Contains(typeof(string).FullName))
{
prop.SetValue(customObject, "abc");
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.