2013-04-30 128 views
1

獲取自定義屬性類型假設我有一個類(像這樣):使用反射

public class User 
{ 
    public Guid Id { get; set;} 
    public DateTime CreationDate { get; set; } 
    public string Name { get; set; } 
    public UserGroup Group { get; set; } 
} 

有沒有辦法讓所有屬性類型不屬於.NET Framework的一部分。 所以在這種情況下,我只想得到UserGroup?那可能嗎 ?

我能想出的最好的事情是一樣的東西:

IEnumerable<Type> types = typeof(User).GetProperties().Where(p => !p.PropertyType.Namespace.StartsWith("System.")).Select(t => t.PropertyType);

但是,這看起來像一個黑客作業。對不起,如果重複,找不到這樣的東西,並抱歉的格式,盡我所能。

回答

1

我認爲你所擁有的可能足夠可靠,你想要什麼。然而,從一個靈活性/可讀性點也許這將是更好的定義,你可以申請在產權層面即

public class User 
{ 
    public Guid Id { get; set; } 
    public DateTime CreationDate { get; set; } 
    public string Name { get; set; } 
    [CustomProperty] 
    public UserGroup Group { get; set; } 
} 

然後,您可以使用反射來查詢所有具有此屬性的屬性自己的屬性類型。這將使您能夠包含/排除任何屬性。


對不起,我忘了提,我不能修改該域的實體。 (不能添加屬性)。

您可以使用MetadataType將屬性添加到基類,例如,

class UserMetadata 
{ 
    ... 
    [CustomProperty] 
    public UserGroup Group { get; set; } 
} 

[MetadataType(typeof(UserMetadata)] 
public class DomainUser : User 
{ 
} 
+0

對不起,我忘了提及我無法修改域實體。 (不能添加屬性)。我感謝你的幫助:) – 2013-04-30 09:44:05

+1

@DimitarDimitrov無後顧之憂,看更新。 – James 2013-04-30 09:52:54

+1

謝謝,這是我沒有想到的方法。我會給它一個鏡頭(看起來更乾淨)。 – 2013-04-30 10:12:01

1

反射總是一種黑客行爲,所以是的,它感覺就像一個hackjob。

但分析實體,類,必須用反射來完成。所以你這樣做是正確的。

一個陷阱。你自己可以在命名空間「System」中創建你自己的類型。這會搞亂你的搜索。你也可以分析Assembly的屬性類型,但是你必須知道所有的.NET程序集,這是一個很大的列表。

+1

雖然你的技術上是正確的,你應該永遠不會實際上是將自己的自定義類型添加到'System'命名空間 - 它違反了[命名空間準則](http://msdn.microsoft.com/zh-CN/library/893ke618(v = vs.71).aspx)。 – James 2013-04-30 10:10:51

0

你所做的一切都很好,你可以這樣做,然後使用Except方法。

public static Type[] GetNonSystemTypes<T>() 
{ 
    var systemTypes = typeof(T).GetProperties().Select(t => t.PropertyType).Where(t => t.Namespace == "System"); 
    return typeof(T).GetProperties().Select(t => t.PropertyType).Except(systemTypes).ToArray(); 
} 
+0

不是很明白爲什麼在這裏引入'Except'有助於此?它所做的只是使代碼更長。 – James 2013-04-30 09:54:25

+0

@詹姆斯只是因爲代碼更長,並不意味着它更糟 - 大部分時間事實上,它是更好的。只是提出一種替代方法呢? – LukeHennerley 2013-04-30 09:58:21

+0

如果它以某種方式確實有幫助,則代碼越長越好 - 但事實並非如此。這就像是在說'你不能寫'var i = 0'' int i;我= 0;'。爲什麼要在兩行中做一些事情,特別是當它不向代碼中添加任何東西時? – James 2013-04-30 10:01:18

0

您的方法有效。我只想說,你也可以嘗試檢查定義類型的Assembly,例如檢查它是否從全局程序集緩存中加載。

bool wasLoadedFromAssemblyCache = typeof(T).Assembly.GlobalAssemblyCache; 
+0

不錯的思維方式,但是,如果Dimitar也將他的DLL放到GAC中呢? – 2013-05-01 08:44:20

+0

@MartinMulder:當然。我的意思是,這個例子更多的是作爲檢查大會所有財產的一個主要啓動者,而不一定是GAC財產。例如,如果自定義類型在同一個程序集中,則可以檢查程序集的名稱。 – gabnaim 2013-05-01 14:46:39