1

我有一个名为 Attribute 的类,其中包含一个列表。如果列表中存在给定的字符串,我希望 get 方法返回 true/false。但是,我希望 set 方法接受一个字符串并将其添加到列表中。

我手边没有编译器,但我的代码或多或少看起来像这样。这可能吗?

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]; }
    }

}
4

4 回答 4

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
于 2012-12-10T21:05:20.580 回答
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 ); }
    }
}

编辑:

它可以完美运行,没有任何问题,但似乎非常无稽之谈。

于 2012-12-10T21:11:39.917 回答
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 做同样的事情时,它违反了 Least Astonishment 原则!更不用说,您作为“索引”传入的值实际上根本不是任何事物的索引。这是合法的,但使用的语法与它的用途完全不同。

老实说,您最好List<string>直接访问并调用其现有的Contains()Add()方法。

于 2012-12-10T21:15:03.507 回答
0

虽然读写属性本质上是一个get方法和一个put方法,并不能真正做这样一对方法不能做的任何事情,但如果方法被包裹在一个“属性”,它对方法可以采用的形式提出了各种限制。最值得注意的是,一个属性可能没有set这些签名的多个重载,不同之处仅在于用于指定新值的参数类型,也可能没有get返回类型与方法的“新值”参数不匹配的set方法,并且其参数与 的所有其他参数不完全匹配set

我不确定通过使语法糖仅可用于满足上述限制的属性可以获得什么。如果读写属性只是与 setter 方法并列的 getter 方法,则可能有一个ReadableFoo带有抽象的抽象类型getproperty Foo,并有一个派生Mutablefoo类型覆盖get并添加一个set. 不幸的是,这是不可能的。最好的办法是让该方法实现一个调用抽象方法ReadableFoo的非虚拟只读属性;Foo然后MutableFoo可以覆盖上述方法,同时用读写属性替换只读属性(get应该链接到上述抽象方法)。

您的特定场景看起来像是一种可行的方式来做您想做的事情,尽管我建议设置a["George"]=false;应该从集合中删除“George”。对于属性设置器具有多个类型重载的许多其他场景可能很有用,但是,由于属性设计不允许,因此根本无法在 .net 中实现。

于 2012-12-16T21:52:33.097 回答