简体   繁体   中英

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

Let's imagine the following situation:

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 );
    }
}

I would like to have the exception correctly raised in A constructor since I want _myFunction to be set to null if b has not been instantiated.

Basically something like:

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

I have tried using the null-conditional operator to do so, but I have being unlucky and I just create a reference to a function that returns null .

The shorter version is probably a = b is null? new A(null): new A(() => b.MyBool); a = b is null? new A(null): new A(() => b.MyBool);

But it's not correct anyway:
Unless b is readonly, it can be modified and set to null before a call to the lambda.

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

A workaround is to use a local (and captured) copy of b to declare the lambda:

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

But this time it doesn't respect good practice (SOLID principles):
A expect a non null function, it's not his responsibility to raise an exception if the caller can't build one .

The code should looks like this:

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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