Reputation: 2347
Considering the following class:
public class Property
{
public string StringValue { get; private set; }
private Property(string value)
{
this.StringValue = value;
}
}
I am trying to write a TrySomething
method (with nullable enabled). I first wrote something like that:
public bool TryGetValue<T>([NotNullWhen(true)] out T? value)
{
value = JsonSerializer.Deserialize<T>(this.StringValue);
return value != null;
}
When using such implementation with reference type, I get the CS8602 warning when writing the following code:
if (property.TryGetValue<Foo>(out var v))
{
v.ToString(); // OK
}
else
{
v.ToString(); // CS8602
}
But when writing it with value types, it does not:
if (property.TryGetValue<int>(out var v))
{
v.ToString(); // OK
}
else
{
v.ToString(); // OK
}
Is it possible to write such methods for value types?
Upvotes: 1
Views: 78
Reputation: 143098
You need to provide "correct" type for your generic (and use Value
instead ToString()
to test the warning):
var property = ...;
if (!property.TryGetValue<int?>(out var i))
{
var value = i.Value; // warning CS8629: Nullable value type may be null.
}
Or constrain the generic parameter to value types:
public class Property
{
public bool TryGetValueType<T>([NotNullWhen(true)] out T? value) where T: struct
{
//...
}
}
The problem is indeed in using value types - for them T
and T?
for unconstrained generic types are treated as the same type (i.e. for you original implementation/call TryGetValue<int>
T
and T?
both are int
, so i.Value
will not even compile) - see more in the answer for Nullability and generics in .NET 6
Upvotes: 1