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

C#属性-返回一种类型并存储另一种类型,c#,properties,C#,Properties,我有一个名为Attribute的类,它包含一个列表。如果列表中存在给定字符串,我希望get方法返回true/false。但是,我希望set方法接受字符串并将其添加到列表中 attribute["Test String 1"] = true; attribute["Test String 2"] = false; 我手边没有编译器,但我的代码或多或少是这样的。这可能吗 class Attribute{ private list<string> m_data; pu

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

attribute["Test String 1"] = true;
attribute["Test String 2"] = false;
我手边没有编译器,但我的代码或多或少是这样的。这可能吗

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

}
类属性{
私有列表m_数据;
公共bool此[string s]{
获取{返回此.m_数据。包含[s];}
设置{this.m_data.Add[s];}
}
}

是的,这将起作用,但是请记住,您必须按照以下说明进行设置。对财产有点奇怪的用法。将值设置为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

是的,这会起作用,但是请记住,您必须按照以下说明进行设置。对财产有点奇怪的用法。将值设置为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

首先,我不确定它是否有效,但我尝试了它,它进行了一些调整:

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 ); }
    }
}
类程序{
静态void Main(字符串[]参数){
属性=新属性();
属性[“string1”]=true;
属性[“string2”]=false;
Console.WriteLine(属性[“string1”]);//True
Console.WriteLine(属性[“string2”]);//True
Console.WriteLine(属性[“string3”]);//False
}
}
类属性{
私有列表m_数据;
公共属性(){
m_data=新列表();
}
公共bool此[string s]{
获取{返回此.m_data.Contains;}
设置{this.m_data.Add(s);}
}
}
编辑:


它工作得非常完美,没有任何问题,但似乎非常荒谬。

首先我不确定它是否有效,但我尝试了它,并对它进行了一些调整:

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 ); }
    }
}
类程序{
静态void Main(字符串[]参数){
属性=新属性();
属性[“string1”]=true;
属性[“string2”]=false;
Console.WriteLine(属性[“string1”]);//True
Console.WriteLine(属性[“string2”]);//True
Console.WriteLine(属性[“string3”]);//False
}
}
类属性{
私有列表m_数据;
公共属性(){
m_data=新列表();
}
公共bool此[string s]{
获取{返回此.m_data.Contains;}
设置{this.m_data.Add(s);}
}
}
编辑:


它可以完美地工作,没有任何问题,但看起来非常荒谬。

这是可行的,但它与直觉背道而驰。对属性(实际上是索引器)的赋值必须包含某种布尔值,该值会被忽略并丢弃:

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
所以,是的,你能做到。但这是个坏主意,因为维护代码的人都不知道发生了什么。这个悬空的布尔值看起来有某种意义,但它没有;当赋值为真和赋值为假做同样的事情时,它违反了最小惊讶的原则!更不用说,作为“索引”传入的值实际上根本不是任何内容的索引。它是合法的,但使用语法的方式与它的目的完全不同


老实说,你最好直接访问
列表
并调用其现有的
Contains()
Add()
方法。

这是可行的,但却与直觉背道而驰。对属性(实际上是索引器)的赋值必须包含某种布尔值,该值会被忽略并丢弃:

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
所以,是的,你能做到。但这是个坏主意,因为维护代码的人都不知道发生了什么。这个悬空的布尔值看起来有某种意义,但它没有;当赋值为真和赋值为假做同样的事情时,它违反了最小惊讶的原则!更不用说,作为“索引”传入的值实际上根本不是任何内容的索引。它是合法的,但使用语法的方式与它的目的完全不同


老实说,你最好直接访问
列表
并调用其现有的
Contains()
Add()
方法。

尽管读写属性本质上是
get
方法和
put
方法,并且不能真正做这两个方法不能做的事情,只有当方法被包装在“属性”中时,才能获得与属性相关联的语法糖,这对方法可以采取的形式造成了各种限制。最值得注意的是,属性不能有多个
set
重载。这些签名仅在用于指定新值的参数类型上不同,也不能有返回类型与
set
方法的“new value”参数不匹配的
get
方法,其参数与
set
的所有其他参数不完全匹配

我不确定通过使语法糖只对满足上述限制的属性可用而获得了什么。如果读写属性只是一个与setter方法并列的getter方法,那么就有可能为属性
Foo
创建一个抽象的
ReadableFoo
类型和一个抽象的
get
,并创建一个派生的
Mutablefoo
类型,该类型覆盖
get
并添加一个
set
。不幸的是,这是不可能的。最好的方法是让
ReadableFoo
方法实现一个调用抽象方法的非虚拟只读
Foo
属性;然后,
MutableFoo
可以覆盖前面的选项