[英]Change a Property's type using reflection
假設我有以下課程:
public class UniqueEntity {
public object Key { get; set; }
}
我想要的是能夠在運行時將Key
的類型從System.Object
更改為System.Int32
。
我想(如果可以的話)完成反射的唯一方法是使用反射 。
屬性的類型可以通過獲得PropertyType
的的屬性PropertyInfo
(遺憾的冗余)。
typeof(UniqueEntity).GetProperty("Key").PropertyType;
問題是它是只讀的。 我不能將值設置為PropertyType = typeof(int);
。
有沒有可能更改屬性類型的方法?
否。任何類成員的類型,無論是字段,屬性還是方法的返回值,以及任何方法參數的類型都是在編譯時確定的。
在您的示例中,您可以在屬性中存儲一個Int32
。 它將被“裝箱”,您可以根據需要將其投射回Int32
。 但是屬性本身的類型將保持Object
。
好吧
主要問題是我上了這個課:
public class UniqueEntity {
[key]
public object Key { get; set; }
}
但是, EntityFramework
在處理object
鍵時會EntityFramework
表的創建。 我的想法是,鍵可以是子類指定的任何類型。
我開始使用泛型:
public class UniqueEntity<T> where T : IComparable, IComparable<T>
{
[Key]
public T Key { get; set; }
}
這在開始時效果很好,但是在創建我的通用存儲庫時會導致嚴重的設計問題(存儲庫定義就像IRepository<T,E>
,而IRepository<E>
就足夠了。
因此, EntityFramework
使用帶有Key
屬性注釋的屬性的PropertyInfo
值來獲取實體的鍵類型。 如果我能(在運行時)將該類型更改為用戶希望的類型,並且完全避免使用泛型,那就太好了。
事實證明,您不能刪除屬性,也不能更改其類型buuuuuut。您實際上可以使用自定義屬性創建一個新的虛擬屬性,並從原始Key
屬性中刪除該屬性!
為此,我們需要一個CustomReflectionContext
(System.Reflection.Context):
public class Modifier : CustomReflectionContext
{
private string propName;
private object propValue;
public Modifier(string propName, object propValue)
{
this.propName = propName;
this.propValue = propValue;
}
protected override IEnumerable<PropertyInfo> AddProperties(Type type)
{
Type newType = MapType(propValue.GetType().GetTypeInfo());
return CreateProperty(newType, propName, o => propValue, (o, v) => propValue = v,
new Attribute[] { new KeyAttribute() }, new Attribute[] { }, new Attribute[] { });
}
protected override IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes)
{
return new Attribute[] { };
}
}
在這個小類的幫助下,我們能夠創建自己的自定義類型以提供給EntityFramework
,並具有一個新屬性,該屬性現在具有[Key]
批注:
var context = new Modifier("NewKey", 0);
var uniqueEntityType = context.MapType(typeof(UniqueEntity).GetTypeInfo());
var keyType = uniqueEntityType.GetProperty("Key").PropertyType;
var keyAttrs = uniqueEntityType.GetProperty("Key").GetCustomAttributes();
var newKeyType = uniqueEntityType.GetProperty("NewKey").PropertyType;
var newKeyAttrs = uniqueEntityType.GetProperty("NewKey").GetCustomAttributes();
Console.WriteLine("Key Property. Type: {0}, Attribute: {1}", keyType, keyAttrs.FirstOrDefault());
Console.WriteLine("NewKey Property. Type: {0}, Attribute: {1}", newKeyType, newKeyAttrs.FirstOrDefault());
Console.ReadLine();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.