除了类参数为null以外的C#可选参数? [英] C# optional parameter besides null for class parameter?

查看:31
本文介绍了除了类参数为null以外的C#可选参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题的最佳解决方案是什么?我正在尝试创建一个具有几个类类型的可选参数的函数,对于这些参数,null是有意义的值,不能用作默认值.就像

What is the best solution to this problem? I'm trying to create a function that has several optional parameters of class types for which null is a meaningful value and cannot be used as a default. As in,

public void DoSomething(Class1 optional1, Class2 optional2, Class3 optional3)
    {
        if (! WasSpecified(optional1)) { optional1 = defaultForOptional1; }
        if (! WasSpecified(optional2)) { optional2 = defaultForOptional2; }
        if (! WasSpecified(optional3)) { optional3 = defaultForOptional3; }

        // ... do the actual work ...
    }

我不能使用 Class1 optional1 = null ,因为null有意义.我不能使用某些占位符类实例 Class1 optional1 = defaultForOptional1 ,因为这些可选参数的编译时常数要求我提供了以下选项:

I can't use Class1 optional1 = null because null is meaningful. I can't use some placeholder class instance Class1 optional1 = defaultForOptional1 because of the compile-time constant requirement for these optional parameters I've come up with the following options:

  1. 使用所有可能的组合提供重载,这意味着此方法有8个重载.
  2. 为每个可选参数包括一个布尔型参数,指示是否使用默认值,这会使签名混乱.

外面有没有人为此提出过一些聪明的解决方案?

Has anyone out there come up with some clever solution for this?

谢谢!

编辑:我最终为编写了一个包装器类,因此不必重复重复 Boolean HasFoo .

edit: I ended up writing a wrapper class for so I didn't have to keep repeating Boolean HasFoo.

    /// <summary>
    /// A wrapper for variables indicating whether or not the variable has
    /// been set.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public struct Setable<T>
    {
        // According to http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx,
        // "[s]tructs cannot contain explicit parameterless constructors" and "[s]truct
        // members are automatically initialized to their default values."  That's fine,
        // since Boolean defaults to false and usually T will be nullable.

        /// <summary>
        /// Whether or not the variable was set.
        /// </summary>
        public Boolean IsSet { get; private set; }

        /// <summary>
        /// The variable value.
        /// </summary>
        public T Value { get; private set; }

        /// <summary>
        /// Converts from Setable to T.
        /// </summary>
        /// <param name="p_setable"></param>
        /// <returns></returns>
        public static implicit operator T(Setable<T> p_setable)
        {
            return p_setable.Value;
        }

        /// <summary>
        /// Converts from T to Setable.
        /// </summary>
        /// <param name="p_tee"></param>
        /// <returns></returns>
        public static implicit operator Setable<T>(T p_tee)
        {
            return new Setable<T>
            {
                IsSet = true
              , Value = p_tee
            };
        }
    }

推荐答案

我至少会考虑为该参数创建新类型:

I would at least consider creating a new type for the parameter:

public void DoSomething(DoSomethingOptions options)

... DoSomethingOptions可能看起来像这样:

... where DoSomethingOptions could look like this:

public class DoSomethingOptions
{
    private Class1 class1;
    public bool HasClass1 { get; private set; }

    public Class1 Class1 
    {
        get { return class1; }
        set
        {
            class1 = value;
            HasClass1 = true;
        }
    }

    ... for other properties ...
}

然后您可以通过以下方式调用它:

Then you can call it with:

DoSomething(new DoSomethingOptions { Class1 = null, Class2 = new Class2() });

您最终不会出现指数级的重载,您仍然可以合理地紧凑地调用它.

You don't end up with an exponential set of overloads, and you can still call it reasonably compactly.

这类似于 Process 使用 ProcessStartInfo 的方法.

这篇关于除了类参数为null以外的C#可选参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆