简体   繁体   English

带有可选参数的 C# 构造函数

[英]C# constructor with optional parameters

I have a simple question about constructors in C#.我有一个关于 C# 中的构造函数的简单问题。 Will these two code snippets behave the same way?这两个代码片段的行为方式相同吗?

Code snippet #1:代码片段#1:

public class foo
{
    public foo(string a = null, string b = null)
    {
      // do testing on parameters
    }
}

Code snippet #2:代码片段#2:

public class foo
{
    public foo()
    {
    }

    public foo(string a)
    {
    }

    public foo(string a, string b)
    {
    }
}

EDIT: And if I add this to the code snippet #1?编辑:如果我将其添加到代码片段 #1 中? It may look a really bad idea, but I'm working on refactoring a legacy code, so I'm afraid if I do sth that will cause damage to other piece of that uses that class.这可能看起来是一个非常糟糕的主意,但我正在重构遗留代码,所以我担心如果我这样做会对使用该类的其他部分造成损害。

public class foo
{
    public foo(string a = null, string b = null)
    {
       if (a == null && b == null)
            {
                // do sth
            }else if (a != null && b == null)
            {
                // do sth
            }
            if (a != null && b != null)
            {
                // do sth
            }
            else
            {

            }
    }
}

The answer is no, the two are not going to behave the same.答案是否定的,两者的行为不会相同。

The first snippet does not let your constructor decide if it has been called with a default parameter for a and/or b , or the caller has intentionally passed null .第一个片段不会让您的构造函数决定是否使用a和/或b的默认参数调用它,或者调用者是否有意传递了null In other words, passing null s intentionally becomes allowed, because you cannot implement a meaningful null check.换句话说,故意传递null是允许的,因为您无法实现有意义的null检查。

Another aspect in which these two code snippets would definitely differ - using constructors through a reflection:这两个代码片段肯定会有所不同的另一方面 - 通过反射使用构造函数:

  • The first snippet would provide one constructor.第一个片段将提供一个构造函数。 Reflection callers would need to deal with passing two parameters to it, or allowing optional parameters with binding flags (look at the demo provided by Jcl ).反射调用者需要处理向它传递两个参数,或者允许带有绑定标志的可选参数(查看Jcl提供的演示)。
  • The second snippet would provide three separate constructors.第二个代码段将提供三个单独的构造函数。 Reflection callers would need to pick the one they wish to use.反射调用者需要选择他们希望使用的那个。

No. Try using named arguments .不。尝试使用命名参数 The overload version will not compile.重载版本将无法编译。 Because a hasn't been given a value in the latter case.因为a没有得到在后一种情况下的值。

var test = new foo1(b: "nope");
var test2 = new foo2(b: "nope");//CS7036 : There is no argument given that corresponds to the required formal parameter of

if your are looking for a way to create an object with optional parameters just create inside your class a static factory method with optional or named parameter:如果您正在寻找一种使用可选参数创建对象的方法,只需在您的类中创建一个带有可选或命名参数的静态工厂方法:

public class Foo
{
    public Foo(string a, string b, string c) { }

    public static Foo createInstance(string a = null, string b = null, string c = null) => new Foo(a, b, c);
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM