C#属性 - 返回一种类型并存储另一种类型

时间:2012-12-10 20:59:15

标签: c# properties

我有一个名为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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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 ); }
    }
}

修改

它没有任何问题,完美无缺,但似乎很无稽之谈。

答案 2 :(得分: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时,它违反了最小惊讶原则,就像分配错误一样!更不用说,作为“索引”传递的值实际上并不是任何东西的索引。它是合法的,但使用的语法与它的目的完全不同。

说实话,只需直接访问List<string>并调用现有的Contains()Add()方法,就可以获得更好的服务。

答案 3 :(得分:0)

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

我不确定通过使语法糖仅适用于符合上述限制的属性而获得的确切结果。如果读写属性只是一个与setter方法并置的getter方法,那么可以为属性ReadableFoo提供一个抽象get类型和一个抽象Foo,并且派生Mutablefoo类型会覆盖get并添加set。不幸的是,那是不可能的。最好的方法是让ReadableFoo方法实现一个非虚拟的只读Foo属性,该属性调用一个抽象方法;然后MutableFoo可以覆盖前面提到的方法,同时用读写方法替换只读属性(get应该链接到前面提到的抽象方法)。

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