2

I do not know what it is called exactly, but for now I will refer to it as 'not null test'. In C# 8 there is a new behavior which allows to test if an object is not null e.g.:

Foo foo = new Foo();

if(foo is { })
{
    //foo is not null
}

You can also extract properties from this object:

public class Foo
{
    public int Bar { get; set; }
}

Foo foo = new Foo();

if(foo is { Bar: var bar })
{
    //Foo is not null and bar contains the value of the property of the foo instance
}

So far so good, but I imagine it to be similar to something like this:

public bool GetBar(Foo foo, out int bar)
{
    if(foo is null)
    {
        return false;
    }

    bar = foo.Bar;
    return true;
}

Which would be used as something like this:

Foo foo = new Foo();

if(GetBar(foo, out var bar))
{
    //Foo is not null and bar contains the value of the property of the foo instance
}

Now my actual question: Is there any way I could use the behavior of ref? Which would look something like this:

if(foo is { Bar: ref var bar })
{
    //Foo is not null and bar contains the value of the property of the foo instance
}

I would understand if this does not exist since out ref does not exist either. So is there any way you can do this, or is there anything that would speak against it?

Palle Due
  • 5,929
  • 4
  • 17
  • 32
Twenty
  • 5,234
  • 4
  • 32
  • 67
  • as far as I understand it, the notation of _{ }_ means 'some object'. Objects do not have a concept of reference variables. The _ref_ keyword is used for function parameters. So the answer would be no – Daniel Schmid Oct 02 '19 at 08:58
  • Well I just use _ref_ just an example, in order to clarify what I mean. – Twenty Oct 02 '19 at 09:00

1 Answers1

2

The pattern you are using is the property pattern from the C#8 pattern matching feature.

The property pattern enables you to match on properties of the object examined.

If I'm getting your question correctly, you'd like not only to get the property value but also a possibility to change that value in the object being matched.

if (foo is { Bar: ref var bar })
{
    bar = 42; // now foo.Bar is 42 too
}

In order that ref semantic to work, it has to be supported by the language and by the compiler.

However, C# doesn't allow you to use ref with a property - and that's true for any C# version. The reason is obvious: your get-set property Bar (as any other C# property) will be compiled to two methods: get_Bar and set_Bar. So in fact you have a method, not a value - thus, you can't ref a value a method returns (okay, there are ref returns, but those don't apply to property getters).

dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • 1
    Thanks for the explanation, I guess it could work with Fields at least then, but I get the problem in general. – Twenty Oct 02 '19 at 09:23