Replies: 9 comments 1 reply
-
See also dotnet/roslyn#4347 |
Beta Was this translation helpful? Give feedback.
-
I think |
Beta Was this translation helpful? Give feedback.
-
Changing the semantics of For the case of public class Person {
public string Name { get; set; }
public bool HasValue => !string.IsNullOrEmpty(Name);
public static person operator |(Person p1, Person p2) {
if(p1==null) return p2;
return p1.HasValue ? p1 : p2;
}
public static bool operator true(Person p) => p != null && p.HasValue;
public static bool operator false(Person p) => p == null || !p.HasValue;
}
...
Person p1 = null;
var p2 = new Person() { Name = string.Empty };
var p3 = new Person() { Name = "Alice" };
var p = p1 || p2 || p3;
Console.WriteLine(p.Name); // Alice
var p4 = p1 || p2;
Console.WriteLine(p4.Name); // "" Using If we go down the road of having |
Beta Was this translation helpful? Give feedback.
-
Couldn't this change the meaning of existing code? I'd prefer to have to explicitly opt in per type by defining a |
Beta Was this translation helpful? Give feedback.
-
@jnm2 I don't think it will, since using the The C# compiler does already do some duck-typing, such as |
Beta Was this translation helpful? Give feedback.
-
@Richiban That's correct if it only applies to value types, but the example was given of the UnityEngine.Object base type, so I assumed it was supposed to work on reference types too. |
Beta Was this translation helpful? Give feedback.
-
In the Nullable reference types proposal, // A strongly typed wrapper for T?
public readonly struct Optional<T>
where T : class
{
private readonly T? _value;
public Optional(T value) => _value = value;
public bool HasValue => _value != null;
public T Value => _value ?? throw new InvalidOperationException("Optional object must have a value.");
public T? GetValueOrDefault() => _value;
} but this struct has some problems: // comparison to Nullable<T>
static void Nullable()
{
// convert null to default(int?).
int? x = null;
// boxed but no allocation. The CLR optimizes default(int?) to null.
object? obj = x;
// null pattern for Nullable<T>.
if (x is null) Console.WriteLine("is null");
// unbox from null. The CLR generates default(int?).
object? @null = null;
int? y = (int?)@null;
// null propagating opeartor. x.HasValue ? x.GetValueOrDefault() + 1 : default(int?);
var z = x + 1;
}
static void MyOptionalWrapper()
{
// I want compile-time null conversion.
Optional<string> x = null;
// I want box optimization to avoid allocation.
object? obj = x;
// Iwant null pattern.
if (x is null) Console.WriteLine("is null");
// I want runtime null conversion.
object? @null = null;
int? y = (int?)@null;
// I want null propagating opeartor. x.HasValue ? x.GetValueOrDefault() + "abc" : default(Optional<string>);
var z = x + "abc";
} So again I want nullable-like types now. |
Beta Was this translation helpful? Give feedback.
-
A use case: https://gist.github.com/ufcpp/ccb6466415b2e5ccec56f140083659cf |
Beta Was this translation helpful? Give feedback.
-
I hope we get this someday. This is one of the primary holes in C#'s "strict" nullability feature. It's incredibly straightforward.
This sort of thing would be a great way to improve the strength of APIs. |
Beta Was this translation helpful? Give feedback.
-
Ported from dotnet/roslyn#15108
nullable-like types
Summary
Reference types and
Nullable<T>
have a special position that they can be use?.
and??
operators. However, we sometimes want to use these operators on other types.?.
and??
should be generalized to arbitrary types with pattern-based approach.Motivation
Example 1: UnityEngine.Object
UnityEngine.Object
- a common base type in Unity Game Engine - overloadsoperator ==
with which a value is treated as null (x == null
is true) if internal native resources have been disposed.However,
?.
and??
for reference types does not calloperator ==
. Instead, the C# compiler emits abrtrue
instruction which simply checks nullability by reference. Thus,?.
and??
onUnityEngine.Object
doesn't work properly:So far, this is not so big problem because Unity uses C# 3.0. However, Unity 5.5 will update C# to 6.0. That behavior of
?.
operator could be a pitfall.Example 2:
Expected<T>
A certain number of developers tend to avoid using null as an invalid value. A reason of it is that null doesn't tell us why a result became invalid. To solve this problem, they prefer a type similar to
expected<T>
in C++ - it is a union type ofT
andException
as following:If C# would have a type like this,
?.
and??
might be allowed on the type.Proposal
I propose that
?.
and??
operators can be used on types that implement certain pattern. I call these types "nullable-like types" named after task-like. How about the pattern like:For example, the
Expected<T>
could implement this pattern as follows:Now, the sample of
Expected<T>
described in the previous section is expanded as follows:Alternatives
There are some alternative approaches that use query expressions and task-like.
Beta Was this translation helpful? Give feedback.
All reactions