编程语言
首页 > 编程语言> > 是否可以限制C#中可选参数的值?

是否可以限制C#中可选参数的值?

作者:互联网

C#允许使用optional parameters:如果在调用中省略了参数,则可以指定值,然后编译器将指定值本身.

例:

public interface IFoo {

    void SomeMethod (int para = 0);

}

这个想法很有用,但是一个问题是可以在类层次结构的不同级别上定义几个“默认值”.例:

public class SubFoo : IFoo {

    public void SomeMethod (int para = 1) {
        //do something
    }

}

如果稍后致电:

SubFoo sf = new SubFoo ();
sf.SomeMethod ();
Foo f = sf;
f.SomeMethod ();

结果是第一次调用使用等于1的参数完成,第二次调用等于0的参数(作为接口).这是有道理的,因为编译器会添加默认值,在第一种情况下,这是SubFoo,因此默认值为1.

当然,要由程序员来保持一致性,但是当程序员在过程中改变主意而忘记修改所有默认值时,容易发生这种精神分裂症.

问题在于,编译器不会警告使用了不同的默认值,而可以通过向上移动类层次结构来检查.另外,有些人可能会模仿默认参数:

public class SubFoo2 {

    public virtual void SomeMethod () {
        SomeMethod(1);
    }

    public void SomeMethod (int para) {
        //do something
    }

}

这允许动态绑定,因此可以始终覆盖.因此,需要非常小心如何“实现”默认值.

有没有办法(例如带有编译器标志)强制检查默认值是否一致?如果不是这样,那么最好至少发出警告,指出某些事情并非真的前后一致.

解决方法:

并不是必须的编译时解决方案-但是您可以为此进行单元测试(我怀疑您正在认真对待单元测试,如果您提出此类问题,则应经常运行它们).这个想法是创建像AssertThatDefaultParametersAreEqual(Type forType)这样的断言方法-查找所有不是抽象的类(使用反射)并从forType继承,然后遍历所有定义了默认参数的方法:

MethodInfo[] methodInfo = Type.GetType(classType).GetMethods(BindingFlags.OptionalParamBinding | BindingFlags.Invoke);

将它们按MethodInfo.Name分组,并在组内检查所有具有默认值的相同参数(可以通过MethodInfo.GetParameters()获得.其中(x => x.IsOptional))具有ParameterInfo.DefaultValue的相同属性.

编辑:顺便说一句.在Mono中可能不起作用,因为编译器没有义务发出例如:可选BindingFlag.

标签:optional-parameters,default-value,c
来源: https://codeday.me/bug/20191028/1954627.html