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?
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 return
s, but those don't apply to property getters).