2012-12-10 70 views
1

我有一個名爲Attribute的類,它包含一個列表。如果給定的字符串存在於列表中,我希望get方法返回true/false。但是,我希望set方法接受一個字符串並將其添加到列表中。C#屬性 - 返回一個類型並存儲另一個類型

我沒有編譯器方便,但我的代碼會或多或少看起來像這樣。這可能嗎?

class Attribute{ 

    private list<string> m_data; 

    public bool this[string s] { 
     get { return this.m_data.Contains[s]; } 
     set { this.m_data.Add[s]; } 
    } 

} 
+2

很確定這是不可能的語法。 –

+1

這真是其中的一次,當它嘗試它是最好的課程。你已經編寫了代碼。獲取一個編譯器並嘗試它。 –

+1

你爲什麼要編寫代碼而不能編譯它?這裏有什麼收穫..?創建一個Method SomeMethod Boolean(通過列表)讓它返回布爾值Duh – MethodMan

回答

2

這種方法很有效,但它的反作用力可怕。分配給你的財產(這實際上是一個索引)必須包含某種布爾值,這被忽視和拋棄的:

Attribute a = new Attribute(); 
a["test"] = true;     // Adds "test" as expected -- but WTF does the true mean? 
a["foo"] = false;     // Adds "foo" -- the false means nothing 
Console.Out.WriteLine(a["test"]); // returns true 

所以,是的,你可以做到這一點。但這是一個糟糕的主意,因爲沒有人維護代碼就會知道發生了什麼。那個懸而未決的布爾看起來像它有某種意義,但它不;它違反了最小驚訝原則時,分配true與分配false相同的事情!更不用說,您作爲「索引」傳入的價值實際上並不是任何東西的索引。這是合法的,但是以與預期目的完全不同的方式使用語法。

誠實地說,您只需直接訪問List<string>並調用其現有的Contains()Add()方法即可。

+0

好吧,我將不得不做更優雅和直觀的事情。謝謝! –

+1

如果寫'false'有將物品從集合中刪除的效果,我認爲這種行爲看起來非常好,直觀。把它看作是一個由布爾值而不是整數索引的稀疏布爾數組。 – supercat

2

是的,這將起作用,但請記住,您必須將其設置爲如下所述。有些奇怪的屬性使用。設置true或false的值會將字符串放入列表中。

attribute["Test String 1"] = true; 
attribute["Test String 2"] = false; 

測試字符串是否是列表與否是你所期望的:

Boolean result1 = attribute["Test String 1"]; // true 
Boolean result2 = attribute["Test String 2"]; // true 
Boolean result3 = attribute["Test String 3"]; // false 
+2

這絕對有效,但它可怕的反直覺。懸掛布爾無操作任務烘烤我的麪條。 –

+0

確實。我完全不知道爲什麼有人會故意這樣做。 (我會把它留給其餘的評論和答案來解釋爲什麼這是一個壞主意。) –

2

首先我不知道它的工作原理,但我想它,並將它與一些調整編譯:

class Program { 
    static void Main(string[ ] args) { 
     Attribute attribute = new Attribute(); 
     attribute[ "string1" ] = true; 
     attribute[ "string2" ] = false; 

     Console.WriteLine(attribute[ "string1" ]); //True 
     Console.WriteLine(attribute[ "string2" ]); //True   
     Console.WriteLine(attribute[ "string3" ]); //False 
    } 
} 

class Attribute { 
    private List<string> m_data; 

    public Attribute(){ 
     m_data = new List<string>(); 
    } 

    public bool this[ string s ] { 
     get { return this.m_data.Contains(s); } 
     set { this.m_data.Add(s); } 
    } 
} 

編輯:

它的工作原理每毫無疑問沒有任何問題,但它似乎非常無聊。

0

雖然讀寫屬性本質上是一個get方法和put方法,並且不能真正做這樣一對方法不能做的任何事情,但只能獲得與屬性相關的語法糖方法被封裝在一個「屬性」中,這會對方法可以採用的形式提出各種限制。最值得注意的是,屬性可能沒有set的多重過載,這些簽名僅在用於指定新值的參數類型方面有所不同,也可能有get方法,其返回類型與set的「新值」參數不匹配方法,其參數不能精確地匹配set的所有其他參數。

我不確定通過使語法糖僅適用於滿足上述限制的屬性而獲得的結果。如果讀寫屬性只是一種與setter方法並列的getter方法,那麼可能會有一個抽象的ReadableFoo類型,其抽象爲get,屬性Foo,並且衍生Mutablefoo類型,該類型會覆蓋get並添加set。不幸的是,這是不可能的。最好的方法是使ReadableFoo方法實現非虛擬只讀Foo屬性,該屬性調用抽象方法;那麼MutableFoo可以覆蓋上述方法,同時用只讀屬性替換隻讀屬性(get應鏈接到上述抽象方法)。

您的特定場景看起來像是一種可行的做法,但我建議設置a["George"]=false;應從集合中刪除「George」。對於屬性設置器有多個類型重載的許多其他場景可能會很有用,但是,無法在.net中實現,因爲屬性設計不允許使用它。

相關問題