I'm new to C# and while exploring the language features, I came across something strange:
struct Foo
{
public Foo Identity() { return this; }
public static void Bar(Foo? foo)
{
Foo foo1 = foo?.Identity().Value; // Does not compile
Foo foo2 = (foo?.Identity()).Value; // Compiles
}
}
Could anyone explain to me why the parenthesis are needed?
Like the letter G, C emerged from the Phoenician letter gimel (centuries later, gimel became the third letter of the Hebrew alphabet). In ancient Rome, as the Latin alphabet was being adapted from the Greek and Etruscan alphabets, G and C became disambiguated by adding a bar to the bottom end of the C.
So the C is indeed a very important letter and has no reason to feel ashamed because it makes no sound on it own. Like a man and a women come together to make a unique "sound" in their marriage, so "C" marries "H" to produce a special combined sound. CH itself has three different sounds.
Quote from wikipedia: "A successor to the programming language B, C was originally developed at Bell Labs by Dennis Ritchie between 1972 and 1973 to construct utilities running on Unix." The creators want that everyone "see" his language. So he named it "C".
In the Latin-based orthographies of many European languages, including English, a distinction between hard and soft ⟨c⟩ occurs in which ⟨c⟩ represents two distinct phonemes. The sound of a hard ⟨c⟩ often precedes the non-front vowels ⟨a⟩, ⟨o⟩ and ⟨u⟩, and is that of the voiceless velar stop, /k/ (as in car).
Could anyone explain to me why the parenthesis are needed?
Because Identity()
returns a Foo
(not a Foo?
) and thus has no Value
property. If foo
is null, the null will propagate through the Identity
call.
When you put parentheses around it, the results of the expression is a Nullable<Foo>
which does have a Value
property.
Also note that if foo
is null, then you will be calling Value
on a Nullable<Foo>
that has no value, and will get an exception at run-time. Some static analyzers will recognize that you have a possible null-reference exception waiting to happen and warn you.
If you expand them to their equivalents without null-propagation it will be more clear:
Foo foo1;
if(foo != null)
{
foo1 = foo.Identity().Value; // not possible - Foo has no Value property.
}
else
{
foo1 = null; // also not possible
}
Foo foo2;
Foo? temp;
if(foo != null)
{
temp = foo.Identity();
}
else
{
temp = null; // actually a Nullable<Foo> with no value
}
foo2 = temp.Value; // legal, but will throw an exception at run-time if foo is null
If
Identity()
returnsFoo
, why doesFoo foo3 = foo?.Identity();
not compile ?
The equivalent of that would be:
Foo foo3
if(foo != null)
{
foo3 = foo.Identity();
}
else
{
foo3 = null; // not possible
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With