简体   繁体   English

如何在C#中包装带有可选参数的方法?

[英]How can I wrap a method with optional parameters in C#?

I have the following C# class (simplified here): 我有以下C#类(在此简化):

internal static class Assertions {
    public static void Assert(bool condition, string message = "Assertion failed") {
        if (!condition) { throw new System.Exception(message); }
    }

    public static void NotNull(object o, string message = "Assertion failed") {
        Assert(!Object.ReferenceEquals(o, null), message);
    }

    public static void EtCaetera(..., string message = "Assertion failed") {
        Assert(..., message);
    }
}

As you can see, I have a method Assertions.Assert() with an optional parameter string message = "Assertion failed" . 如您所见,我有一个Assertions.Assert()方法,带有可选参数string message = "Assertion failed"

When I write a wrapper around that method, I'd like the wrapper to have a default parameter string message , but I'd like to avoid repeating the default value ( "Assertion failed" ) because that violates the DRY principle: if I want to change the message "Assertion failed" to "I crashed" , I'll have to change that default value in many places. 当我围绕该方法编写包装器时,我希望包装器具有默认的参数string message ,但是我想避免重复默认值( "Assertion failed" ),因为这违反了DRY原理:如果我想要要将消息"Assertion failed"更改为"I crashed" ,我将不得不在许多地方更改该默认值。

How can I pass-through the "missingness" of the optional parameter? 如何传递可选参数的“缺失”? I'm looking for something like: 我正在寻找类似的东西:

public static void NotNull(object o, string message = Type.Missing) {
    Assert(!Object.ReferenceEquals(o, null), message);
}

ANother option would be not to use optional parameters and provide two versions of each method, but that would quickly get cumbersome. 另一个选择是不使用可选参数,并为每个方法提供两个版本,但这会很快变得麻烦。

Optional parameters are resolved at compile time and they're not replaced for special values so you don't have many options here. 可选参数是在编译时解析的,不会被替换为特殊值,因此此处没有太多选项。

My suggestion, if you don't want to repeat yourself, is to introduce a special value (to mimic what Type.Missing is): 如果您不想重复自己的话,我的建议是引入一个特殊值(以模仿Type.Missing是什么):

internal static class Assertions {
    public static void Assert(bool condition, string message = null) {
        if (!condition) {
            throw new System.Exception(message ?? "Assertion failed");
        }
    }
}

internal static class Wrapper {
    public static void Assert(bool condition, string message = null) {
        Assertions.Assert(condition, message);
    }
}

This has another (IMO big) advantage: if you change your error message (or you'll localize it ) you won't have to change all your code (and existing compiled libraries will be updated ). 这还有另一个(IMO大的)优势:如果您更改错误消息 (或将其本地化 ),则不必更改所有代码(现有的编译库将被更新 )。 Don't forget that, in your original code, a call like this: 不要忘记,在您的原始代码中,这样的调用:

Assertions.Assert(value > 0);

Will be translated (and compiled, even if you use a const field) to: 将被转换(和编译,即使您使用const字段)为:

Assertions.Assert(value > 0, "Assertion failed");

So, even if you'll change your default message, compiled assemblies won't get updated. 因此,即使您更改默认消息,编译后的程序集也不会得到更新。

I prefer to use null as the default value for optional arguments. 我更喜欢将null作为可选参数的默认值。

internal static class Assertions {
    private const string DefaultMessage = "Assertion failed";

    public static void Assert(bool condition, string message = null) {
        message = message ?? DefaultMessage;
        if (!condition) { throw new System.Exception(message); }
    }

    public static void NotNull(object o, string message = null) {
        message = message ?? DefaultMessage;
        Assert(!Object.ReferenceEquals(o, null), message);
    }

    public static void EtCaetera(..., string message = null) {
        message = message ?? DefaultMessage;
        Assert(..., message);
    }
}

The default value needs to be specified on the first method called (ie your wrapper) as this is where the value is applied to the parameter. 默认值需要在第一个方法(即包装器)上指定,因为这是将值应用于参数的位置。 Type.Missing is a special value that has meaning in COM interop. Type.Missing是一个特殊的值,在COM互操作中具有含义。 Here are some options you could try that may suit your needs. 您可以尝试以下一些适合您需求的选项。

  1. Use the OptionalAttibute on the base method and specify the default value on the overridden method. 在基本方法上使用OptionalAttibute ,并在覆盖的方法上指定默认值。

     class Class2 : Class1 { public override string MethodWithOptParams(string message = "default message") { return base.MethodWithOptParams(message); } } class Class1 { public virtual string MethodWithOptParams([Optional]string message) { return message; } } 
  2. Declare your default values as constants in and apply the same constant as the default value. 将默认值声明为in,并应用与默认值相同的常量。

     class Class2 : Class1 { public override string MethodWithOptParams(string message = DefaultMessage) { return base.MethodWithOptParams(message); } } class Class1 { protected const string DefaultMessage = "default message"; public virtual string MethodWithOptParams(string message = DefaultMessage) { return message; } } 
  3. Use null as the default value in your wrapper and code the two alternative calls to the base method. 在包装器中将null用作默认值,并对对基本方法的两个替代调用进行编码。

     class Class2 : Class1 { public override string MethodWithOptParams(string message = null) { if (message == null) { return base.MethodWithOptParams(); } else { return base.MethodWithOptParams(message); } } } class Class1 { public virtual string MethodWithOptParams(string message = "default message") { return message; } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在C#抽象方法中指定可选的匿名可枚举参数 - how to specify optional anonymous ienumerable parameters in c# abstract method 如何使用反射调用带有可选参数的方法 c# - How to call Method with optional parameters using reflections c# 具有可选参数的C#Web服务方法 - C# Web Service Method with Optional Parameters C#:我可以或如何为方法参数指定属性吗? - C#: Can I or how to assign attributes to method parameters? C# - 在一个方法中,我怎样才能有 2 个参数是一个? - C# - In a method, how can I have 2 parameters that are one? 在C#4中,如何在具有重载构造函数的父类的子类中具有带可选参数的构造函数? - In C# 4, how can I have constructors with optional parameters in a subclass of a parent with an overloaded constructor? 如何在 C# 中使用可选参数? - How can you use optional parameters in C#? C# 如何将可选参数作为集合传递? - C# how do I pass optional parameters as a collection? C#:使用可选参数和命名参数覆盖方法:意外结果 - C# : overriding Method with optional parameters & named parameters : Unexpected Result 我可以在C#函数中为参数或可选参数赋予默认值吗? - Can I give a default value to parameters or optional parameters in C# functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM