首页 文章

可选参数和接口 - 意外结果[重复]

提问于
浏览
2

这个问题在这里已有答案:

我支持一些具有可选参数和接口的代码 .

作为一个简化示例:接口中的默认值为2,实现类中的默认值为1 .

public interface IOptionalInterface
{
    int Get(int x = 2);
}

public class ClassX : IOptionalInterface
{
    public int Get(int x = 1)
    {
        return x;
    }
}

正如我所料,这段代码通过了 .

Assert.AreEqual(new ClassX().Get(), 1);

但是,当我将类作为接口传回,并稍后调用它时,我从接口获取可选参数;这让我很吃惊 .

private IOptionalInterface Build()
    {
        return new ClassX();
    } 

    public void Expect1()
    {
        var y = Build();
        Assert.AreEqual(y.Get(), 1);  // fails, it returns 2.
    }

我缺少什么主要的设计考虑因素才能优先考虑?

是否有一种干净的方法来确保实现类设置默认值?

2 回答

  • 3

    可选参数是在调用点调用的纯编译时功能 .

    使用可选参数调用方法时,编译器将查找该参数的默认值,并在调用中插入该文字值 .
    因此,默认值将根据调用点的编译时类型进行解析 .

  • 1

    这是因为 - 像扩展方法一样 - 可选参数是编译技巧而不是真正的语言功能 .

    如此恰当 - 用扩展方法解决问题:

    public interface IDoSomething {
        void DoThis(int parameter);
    }
    
    public static class DoSomethingDefaults {
        public static void DoThis(this IDoSomething x) {
            x.DoSomething(123); //default value
        }
    }
    
    ///
    new ClassThatImplementsDoSomething().DoThis();
    new ClassThatImplementsDoSomething().DoThis(456);
    

    它不像真正的可选参数那样超级光滑,但是对于大多数用途来说,它们做同样的事情并且正常工作 .

    保持默认设置与您的界面(我甚至推荐相同的文件),并希望您的项目的新手能够追踪正在发生的事情并不会太难 .

相关问题