继承可选参数基本方法的歧义

时间:2011-09-19 16:43:31

标签: c# inheritance c#-4.0

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

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

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

  

成员'SpecificMerchant.WriteResults()'不会隐藏   继承的成员。新关键字不是必需的。

为什么呢?在实践中,我不是要覆盖父方法吗?

2 个答案:

答案 0 :(得分:2)

不,你没有压倒它。您提供的方法具有不同的签名。考虑一下:

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

可能调用SpecificMerchant中的方法吗?否 - 您已指定参数,SpecificMerchant.WriteResults未指定任何参数。仅这一事实表明它无法覆盖Merchant.WriteResults

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

答案 1 :(得分:1)

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

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

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

为了获得良好的资源,我建议阅读James Michael Hare's post on Optional Parameters - 当你将可选参数与继承混合时,他会讨论像这样的陷阱。