【问题标题】:Ambiguity with inheriting an optional-parameter base method继承可选参数基本方法的歧义
【发布时间】:2011-09-19 16:43:31
【问题描述】:

我有一个带有一个可选默认参数的基类,子类会自动为其提供一个值:

public class Merchant
{
    public string WriteResults(List<string> moreFields = null)
    {

        List<string> ListOfObjects = new List<string>() {Name, Address};
        if (moreFields != null)
        {
            ListOfObjects.AddRange(moreFields);
        }
            return ListOfObjects.ToString() //not real output
}


public class SpecificMerchant : Merchant 
{   
    new public string WriteResults()
        {
            return ((Merchant)this).WriteResults(new List<string>() {
                    Address, Phone //class-specific parameters
            });
        }
}

我在调用SpecificMerchant.WriteResults 时使用了new 关键字,因为父类和基类都可以不带参数,但编译器说这是不必要的:

成员“SpecificMerchant.WriteResults()”不隐藏 继承的成员。 new 关键字不是必需的。

为什么?在实践中,我不是重写父方法吗?

【问题讨论】:

标签: c# inheritance c#-4.0


【解决方案1】:

不,你没有覆盖它。您正在提供具有不同签名的方法。考虑一下:

new SpecificMerchant().WriteResults(new List<string>());

可能可以调用SpecificMerchant中的方法吗?否 - 您指定了一个参数,而 SpecificMerchant.WriteResults 没有指定任何参数。仅这一事实就表明它不可能覆盖Merchant.WriteResults。

您的代码肯定会引起混淆,因为类型层次结构中的重载通常甚至 没有 可选参数 - 但就 C# 编译器和 CLR 而言,它们是非常不同的方法。 . 碰巧两者都会验证没有指定参数的调用,但这是另一回事。

【讨论】:

    【解决方案2】:

    因为可选参数是编译时构造,而不是运行时构造。

    你的基类总是会有一个带有一个参数的方法。如果您在没有参数的情况下调用该方法,编译器只会在编译时“替换”null 。

    话虽如此,我会避免尝试执行您在上面实施的操作。即使你删除了new 关键字,这将让它编译,你会增加很多混乱。如果需要,我个人会将基类实现虚拟化,或者向基类添加两个方法并覆盖一个,而不是使用可选参数。

    对于一个好的资源,我建议阅读James Michael Hare's post on Optional Parameters - 他讨论了当您将可选参数与继承混合时的陷阱,就像这个一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 2017-10-24
      • 2014-08-15
      • 1970-01-01
      相关资源
      最近更新 更多