【问题标题】:Can I override properties in c#?我可以覆盖 c# 中的属性吗?
【发布时间】:2015-12-10 03:22:36
【问题描述】:

我的班级有两个属性:

public bool this[string i]
public double this[string i]

然后当我想给他们一个值时,区分它会出错。

 Class cl = new Class() ;
 cl["something"] = true; //error
 cl["something_else"] = 10.1; //error

有没有办法不向其中一个属性添加参数而只是覆盖它?

【问题讨论】:

标签: c# class overriding


【解决方案1】:

问题不在于用法,而在于声明。由于返回类型不参与重载解析,这两个索引器(不是属性)具有相同的签名,因此程序不会编译。

来自 C# 规范的“3.6 签名和重载”部分:

方法的签名由方法名、类型参数个数和类型组成 以及每个形式参数的种类(值、引用或输出),按从左到右的顺序考虑。 出于这些目的,出现在形式参数类型中的方法的任何类型参数都是 不是通过它的名字来标识的,而是通过它在方法的类型参数列表中的序号位置来标识的。 签名 的方法具体不包括返回类型,可以为 最右边的参数,也不是可选的类型参数约束。

您可能不得不回退到使用普通的旧 getter/setter(例如:bool GetStatus(string i)double GetPercentage(string i),或重新考虑您的设计。

【讨论】:

    【解决方案2】:

    不,不能仅通过返回类型来区分属性或方法。

    索引器的签名规则在 C# 规范的“10.9 索引器”部分中指定:

    索引器的形式参数列表定义了索引器的签名(第 3.6 节)。 具体而言,索引器的签名由其形式参数的数量和类型组成。形式参数的元素类型和名称不是索引器签名的一部分。
    索引器的签名必须不同于在同一类中声明的所有其他索引器的签名。

    (我的重点)

    来自“3.6 签名和重载”:

    方法的签名由方法的名称、类型参数的数量以及每个形式参数的类型和种类(值、引用或输出)组成,按从左到右的顺序考虑。出于这些目的,出现在形参类型中的方法的任何类型参数都不是通过其名称来标识的,而是通过它在方法的类型参数列表中的序号位置来标识的。 方法的签名具体不包括返回类型,params修饰符 可以为最右边的参数或可选的类型参数约束指定。

    (再次强调)

    另外,在同一章节的底部:

    另外,请注意,返回类型和 params 修饰符不是签名的一部分,因此不能仅基于返回类型或包含或排除 params 修饰符来重载.

    (再次强调)

    在同一个类上拥有多个索引器的唯一方法是给它们不同的参数类型或不同数量的参数。

    我的建议是执行以下操作之一:

    • 切换到使用命名属性,如果您有多个索引器,那么仅使用索引器会得到什么并不完全清楚
    • 将索引器封装到不同的对象中,这样您就可以编写instance.Percentages["name"]instance.Flags["name"]。您不能在 C# 中命名索引器,但可以使用从属性返回的另一个对象公开它们。

    【讨论】:

    • 最后的解决方案(封装)是(恕我直言)这样做的正确方法。 +1
    【解决方案3】:

    这不是有效的 c# 语法。 查看此页面以获取有关如何覆盖 c# 属性的说明:https://*.com/a/8447846/3905529

    【讨论】: