Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的重载属性#_C#_Properties_Overloading - Fatal编程技术网

C# C语言中的重载属性#

C# C语言中的重载属性#,c#,properties,overloading,C#,Properties,Overloading,好的,我知道C#中不支持属性重载-大多数参考文献都通过引用单个方法的不同返回类型问题来解释它。然而,二传手呢?我想直接将值赋值为字符串或对象,但只返回字符串 像这样: public string FieldIdList { get { return fieldIdList.ToString(); } set { fieldIdList = new FieldIdList(value); } } public FieldIdList

好的,我知道C#中不支持属性重载-大多数参考文献都通过引用单个方法的不同返回类型问题来解释它。然而,二传手呢?我想直接将值赋值为字符串或对象,但只返回字符串

像这样:

    public string FieldIdList
    {
        get { return fieldIdList.ToString(); }
        set { fieldIdList = new FieldIdList(value); }
    }

    public FieldIdList FieldIdList 
    {
        set { fieldIdList = value; }
    }
    private FieldIdList fieldIdList;
为什么不允许这样做?我还看到,“属性”只是在编译时创建getter/setter函数。有可能创造我自己的吗?比如:

    public void set_FieldIdList(FieldIdList value)
    {
        fieldIdList = value;
    }

那也会做同样的事情。想法?

属性实际上是一对get/set方法(其中一个可能会被忽略),但是属性本身有额外的元数据,这使得它首先成为一个属性,而不仅仅是两个方法

因为即使只有setter,属性签名仍然无效,因为返回类型不同。如果你需要这个,不要使用财产;仅设置属性无论如何都不是一件好事。

一种方法(您可能会争论这是否是一个好的设计选择)是添加第二个属性,它以不同的形式访问数据

但是,由于它将要解析字符串(进行重要的工作),因此最好不要为此使用属性,而是添加允许您以字符串形式获取/设置数据的方法


我会选择fieldIdList提供ToString()和TryParse()接口,然后如果您需要它作为字符串,您可以调用myObject.fieldIdList.ToString()等。这将整洁地封装所有内容,允许您在代码中的任何位置转换为字符串格式,而不仅仅是作为其他类的成员访问fieldIdList时,并且使客户端代码非常清晰易懂。

如果您希望能够将属性设置为字符串或对象,那么您只需使用对象作为属性的类型,因为它是基类(您可以将字符串传递给接受对象的属性)。这似乎不是特别好的设计决策,但它是可以做到的。也许您需要进一步解释您试图实现的目标?

从C#7开始,您不能重载C#属性

但是,包括您的财产在内的重新设计是可能的

可以使用set块中的条件调用私有函数, 这可能会过载

public string FieldIdList
{
    get { return fieldIdList.ToString(); }
    set { fieldIdList = ChangeFieldList(value); }
}

private string ChangeFieldIdList(int i) {
    return i.ToString();
}
这个例子只是为了不显示使用私有函数的重新设计考虑
在集合块内调用。

那么,编译器为一对方法创建一个签名,这就是防止额外重载的原因?这仅仅是为了方便物业,还是为了更多?有什么额外的数据使它成为一个财产?不完全是。正如不能有两个具有相同名称的不同类型的变量一样,也不能有两个具有不同类型和相同名称的属性。问题是一样的,编译器不知道在什么情况下使用哪个变量或属性。因此,即使您选择了访问器,以便get/set方法不会产生冲突,如果签名相同,编译器也不能允许您多次使用相同的属性名(请注意,您可能有多个索引器属性,因为在这种情况下,即使使用相同的名称,签名也会有所不同)@Lucero:如果属性的类型是由get方法的返回类型强加的呢?在这种情况下,我们可以有许多类型的setter,set方法的主体处理必要的转换。编译器没有任何混乱,我们仍然得到了强类型化,因为集合方法是根据方法重载规则选择的,而不需要使用
对象
属性接受任何东西来解决提问者的问题(以及我的问题)。@paercebal,这很好,但会导致其他问题,例如如何处理虚拟属性和抽象属性等。事实上,属性是一种构造,它最多允许一个getter和一个setter,每个getter和setter具有明确定义的签名。如果这不合适,那么无论如何不要使用属性,而是返回到一堆ob setter方法,这样您就可以重载这些方法。@Lucero:
如何处理虚拟和抽象属性?
因为getter和setter都是方法,它们的虚拟抽象性不应该是问题<代码>属性是一种构造,它最多允许一个getter和一个setter,每个getter和setter都有一个明确定义的签名:我的观点完全正确。我相信,setter的值类型被限制为getter的返回类型这一事实是一个设计决策(好或坏,这无关紧要),而不是技术限制。下一个问题是:在C语言中增加setter重载的可能性不是很容易吗?提问者非常清楚:他想为set方法提供方法重载。这与编写多个重载的
SetField(Field-Field)
SetField(string-Field)
方法一样合法。@DanDiplo使用对象并没有真正的帮助,因为OP只希望接受两种类型,一个string和自定义FieldIdList。
string
重载是一个示例,而不是一般情况。提问者希望为属性的set方法提供一个重载,对于类型a和类型B,不管它们的类型是什么。让我们说,它们对属性的真正底层类型的“转换”不是“重要的工作”。那么在C#IMHO中使用属性将是一个很好的自然解决方案。@paercebal:作为一种最佳实践,属性应该具有无副作用的简单实现——程序员应该能够将属性当作一个简单的成员变量来处理(也就是说,假设将其设置为快速/高效、无损且不会引发事件或异常)。在任何其他情况下,将其作为方法实现是更好的做法。属性的重载意味着该属性是一个非平凡的实现,并且隐藏了某种程度的复杂性。这并不总是坏事,但经常是坏事