簡體   English   中英

C# 使用反射進行類型比較

[英]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,我認為是不安全的檢查 但如果沒有找到其他解決方法,我將使用我的方法。 在調試模式下, propTypeFullName是:

      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<>)表示常規類型。 它不是一個普通類型:相反,它是一個泛型類型定義。 這就是IsAssignableFromIsSubclassOf等不起作用的原因。 如果以下條件為真,則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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM