我在 C# 中有以下類:
public class WorkOrderStatus : ICustomEnum<WorkOrderStatus>
{
}
在運行時,我需要確定以下類的屬性是否實作了自定義介面。
public class WorkOrder{
public WorkOrderStatus Status {get;set;}
}
所以我嘗試執行以下操作(使用反射來弄清楚):
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum));
但這表示 ICustomEnum 需要泛型型別。所以我嘗試執行以下操作,但它不起作用:
var type = prop.GetType();
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum<typeof(type)>));
說型別是一個變數,但像型別一樣使用
[編輯 1]
稍后我需要能夠WorkOrderStatus通過像這樣的反射來創建實作此介面的任何其他類的實體:
var instance = (ICustomEnum<WorkOrderStatus|SomeOtherStatus...>)Activator.CreateInstance(prop.PropertyType);
uj5u.com熱心網友回復:
這樣做很簡單IsAssignableTo:
Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);
而且,您可能會發現這typeof(ICustomEnum<>).MakeGenericType(propertyType);可以直接在您的代碼中解決您的問題。
所以,而不是typeof(ICustomEnum<typeof(type)>)你寫typeof(ICustomEnum<>).MakeGenericType(type).
以下是您將如何使用反射來呼叫方法,以便您可以從運行時型別移回編譯時型別。
void Main()
{
Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);
if (implements)
{
object propertyInstance = Activator.CreateInstance(propertyType);
var method =
this
.GetType()
.GetMethod("SomeMethod", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(propertyType);
method.Invoke(this, new[] { propertyInstance });
}
}
private void SomeMethod<T>(ICustomEnum<T> customEnum)
{
Console.WriteLine($"Success with {typeof(T)}");
}
輸出以下內容:
Success with WorkOrderStatus
這是運行上述代碼所需的雜項代碼:
public class WorkOrderStatus : ICustomEnum<WorkOrderStatus> { }
public interface ICustomEnum<T> { }
public class WorkOrder
{
public WorkOrderStatus Status { get; set; }
}
uj5u.com熱心網友回復:
您可以GetGenericTypeDefinition用于此目的。例如,
propertyInfo.PropertyType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>));
要檢索實作特定通用介面的 Type 的所有屬性,您可以
var properties = typeof(WorkOrder).GetProperties();
var result = properties.Where(property=>property.PropertyType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>)));
uj5u.com熱心網友回復:
你可以試試這個
bool implements = typeof(WorkOrder).GetProperties()
.Any(p => p.PropertyType.GetInterfaces().Any(pt => pt.Name ==typeof(ICustomEnum<>).Name));
或通用變體
var contains=ContainsInterface<WorkOrder,ICustomEnum<WorkOrder>>();
public static bool ContainsInterface<T1,T2>()
{
return typeof(T1).GetProperties().Any(p => p.PropertyType.GetInterfaces()
.Any(pt => pt.Name ==typeof(T2).Name));
}
或屬性串列
printProperties<WorkOrder,ICustomEnum<WorkOrder>>();
public static void printProperties<T1,T2>()
{
foreach (var property in typeof(T1).GetProperties())
{
var contains= property.PropertyType.GetInterfaces()
.Any(pt => pt.Name ==typeof(T2).Name);
if(contains)Console.WriteLine("Property " property.Name " contains interface " typeof(T2).Name);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/401135.html
