繁体   English   中英

是否可以使用空条件运算符将 Func<> 设置为 null?

[英]Is it possible to use a null-conditional operator to set a Func<> to null?

让我们想象一下以下情况:

public class A
{
    private readonly Func<bool> _myFunction;
    ...
    public A(Func<bool> myFunction)
    {
        _myFunction = myFunction ?? throw new ArgumentNullException();
    }
}
public class B
{
    private bool _myBool;
    public bool MyBool => _myBool;
}
public class C
{
    A a;
    B b;
    ...
    public void SomeFunction()
    {
        a = new A( () => (bool)b?.MyBool );
    }
}

我希望在A构造函数中正确引发异常,因为如果b尚未实例化,我希望将_myFunction设置为 null。

基本上是这样的:

if (b == null) {a = new A(null);} else {a = new A(() => b.MyBool);}

我曾尝试使用 null 条件运算符来这样做,但我很不走运,我只是创建了对返回null的 function 的引用。

较短的版本可能是a = b is null? new A(null): new A(() => b.MyBool); a = b is null? new A(null): new A(() => b.MyBool);

但这无论如何都不正确:
除非b是只读的,否则可以在调用null之前将其修改并设置为 null。

b = null;
a.CallMyFunction(); // will call the lambda and fail to evaluate b.MyBool

解决方法是使用b本地(和捕获)副本来声明 lambda:

var b2 = b;
a = b2 is null ? new A(null) : new A(() => b2.MyBool)

但这次它不尊重良好实践(SOLID 原则):
A expect a non null function,如果调用者不能构建异常,他没有责任引发异常

代码应如下所示:

a = BuildAFromB(b); // pass a copy of b
// ....

// static to avoid ambiguity between the field b and the argument b
// To avoid this, it's in guidelines to prefix fields name with _
// _a, _b, ...
static A BuildAFromB(B b)
{
    if (b is null)
        throw new ArgumentException();

    return new A(() => b.MyBool);
}

暂无
暂无

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

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