2012-01-27 86 views
1

我編碼自定義屬性,而不是標記接口如何命名使用屬性的類?

public class FooAssignableAttribute : Attribute 
{ 
    ... 
} 

[FooAssignable] 
public class Foo 
{  
    ... 
} 

我不能像這樣的代碼字典?

Dictionary<string, FooAssignable> dictionary; 

避免標記接口,我嘗試使用自定義attrutes。爲什麼我不能編寫上面的代碼?

+0

你不能這樣做。屬性不是C#類型系統的一部分,這不是您可以制定的限制。爲什麼你需要基於屬性來表達這個約束? – millimoose 2012-01-27 23:03:02

+0

而且?所以你不想,但這是需要做的......這是什麼問題? – 2012-01-27 23:03:24

+0

我爲您格式化了您的代碼示例。爲了將來的參考,代碼示例需要縮進四個空格才能正確顯示(或者您可以使用編輯框上方的「{}」按鈕)。 – 2012-01-27 23:07:55

回答

2

不,這不起作用。 C#中泛型集合(或其他泛型)的參數類型必須是可聲明類型,屬性只能作爲元數據存在。

您不能擁有FooAssignable類型的對象。您可以擁有一個具有FooAssignable屬性的對象,但這與將它作爲超類型不同。 FooAssignable不是類或接口,也不是有效的類型說明符。 FooAssignableAttribute是,但這是引用屬性本身的類型,而不是使用該屬性標記的項目。

請注意,在字典中,索引器的輸出類型是您提供的輸出類型。但是你不能有一個FooAssignable類型的變量 - 你可以有一個已經用FooAssignable標記的類型的變量,但是沒有一個類型適合所有類型的基類。由於該類型的聲明是非法的,因此該字典將具有非法的,不存在的類型作爲來自其索引器的獲取器的返回類型,以及許多其他地方。 C#類型檢查不能通過具有屬性存在檢查的通用機制自發替換。

任何你希望類型系統檢查你的東西都必須是類型系統的一部分。屬性評估沒有定義類型,所以類型系統不能爲你做這個;同時,泛型是最直接與類型系統交互的語言的一部分。你將不得不通過類型系統來執行這樣的檢查,而這意味着將FooAssignableAttribute提升爲接口(IFooAssignable?)。

+0

我沒有想到它。但是,你能解釋一下我最後一句話嗎? – 2012-01-28 05:27:17

+0

據我所知,你需要一個字典將字符串映射到具有屬性FooAssignable的對象。這是不可能的,因爲FooAssignableAttribute作爲一個類型只是指屬性本身 - 它並不意味着「具有FooAssignable屬性的對象」。但是如果你創建了一個標記接口IF​​ooAssignable,並且實現了將你的FooAssignableAttribute實現的所有東西,那麼你可以創建一個從字符串到IFooAssignable的字典。 IFooAssignable是可用對象可以使用的類型。泛型集合要求「是a」,但與屬性的關係是「有a」。 – 2012-01-30 19:50:40

+0

+1自從OP切換回答後,您看起來確實瞭解他。 – LarsTech 2012-01-31 00:10:31

1

FooAssignableAttribute是班級的名字。如果你想在代碼中引用這個類,你必須使用它的名字。

離開過尾隨「Attribute」的簡寫,只有當你使用它作爲一個屬性,如您[FooAssignable]例如上述作品。當您將它用作類時(例如,作爲變量聲明或泛型類型參數)時,您必須使用其類名稱。

1

只要改變你的類名(如果可能):

public class FooAssignable : Attribute 
{ ... } 
+0

這並沒有解決問題 - Darf Zon希望收集(使用FooAssignable標記的對象),而不是收集(FooAssignable類型的對象),這將實現這一點。這是一個範圍問題,沒有一個實現FooAssignable的超類,沒有接口就沒有辦法做到這一點。 – 2012-01-27 23:15:27

+0

@AdamNorberg當我回答時,Joe White幾乎覆蓋了我的想法。如果您查看問題的修訂歷史記錄,它最初是關於嘗試在關鍵字末尾使用沒有「屬性」擴展名的類名稱,例如屬性名稱裝飾類的方式。據我所知,沒有一個規則,屬性「必須」以名稱「屬性」附加到它們。只是給OP另一個選擇,因爲他不想要真正的長名。 – LarsTech 2012-01-27 23:30:52

+0

通過我的回答,這個問題被重寫了一半。我認爲投訴不是關於名稱的長度,而是它不是收集FooAssignableAttribute的對象,而應該是「帶有FooAssignableAttribute標記的Object的對象」,它本身不是本身一種。不過,我似乎已經讀錯了,因爲接受了你的答案! – 2012-01-27 23:47:28

0

配合好你自己的風格指南或選擇存在任何風格指南。

+0

這不是樣式問題 - 這是C#類型系統的基礎,綁定屬性不是類型。存在屬性類型,但帶有屬性的對象不是可分配的類型。 – 2012-01-27 23:17:34