Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия были зафиксированы в соответствующих совещаниях по разработке языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Вопрос чемпиона: https://github.com/dotnet/csharplang/issues/3297
Сводка
Разрешить заметки, допускающие значение NULL, для параметров типа, которые не ограничены типами значений или ссылочными типами: T?
.
static T? FirstOrDefault<T>(this IEnumerable<T> collection) { ... }
заметка ?
В C#8 ?
заметки можно применять только к параметрам типа, которые были явно ограничены типами значений или ссылочными типами.
В C#9 ?
заметки можно применять к любому параметру типа независимо от ограничений.
Если параметр типа явно не ограничен типами значений, заметки могут применяться только в контексте #nullable enable
.
Если параметр типа T
заменен ссылочным типом, T?
представляет экземпляр ссылочного типа, допускающий значение NULL.
var s1 = new string[0].FirstOrDefault(); // string? s1
var s2 = new string?[0].FirstOrDefault(); // string? s2
Если T
заменен типом значения, T?
представляет экземпляр T
.
var i1 = new int[0].FirstOrDefault(); // int i1
var i2 = new int?[0].FirstOrDefault(); // int? i2
Если T
заменен аннотированным типом U?
, то T?
представляет аннотированный тип U?
вместо U??
.
var u1 = new U[0].FirstOrDefault(); // U? u1
var u2 = new U?[0].FirstOrDefault(); // U? u2
Если T
заменен типом U
, T?
представляет U?
даже в контексте #nullable disable
.
#nullable disable
var u3 = new U[0].FirstOrDefault(); // U? u3
Для возвращаемых значений T?
эквивалентно [MaybeNull]T
; для значений аргументов T?
эквивалентен [AllowNull]T
.
Эквивалентность важна при переопределении или реализации интерфейсов из сборки, скомпилированной с помощью C#8.
public abstract class A
{
[return: MaybeNull] public abstract T F1<T>();
public abstract void F2<T>([AllowNull] T t);
}
public class B : A
{
public override T? F1<T>() where T : default { ... } // matches A.F1<T>()
public override void F2<T>(T? t) where T : default { ... } // matches A.F2<T>()
}
ограничение default
Для совместимости с существующим кодом, где переопределённые или явно реализованные универсальные методы не могли включать явные предложения ограничений, T?
в переопределённом или явно реализованном методе рассматривается как Nullable<T>
, где T
является типом значения.
Чтобы разрешить аннотации для параметров типа, ограниченных ссылочными типами, в C#8 были разрешены явные ограничения where T : class
и where T : struct
для переопределенного или явно реализованного метода.
class A1
{
public virtual void F1<T>(T? t) where T : struct { }
public virtual void F1<T>(T? t) where T : class { }
}
class B1 : A1
{
public override void F1<T>(T? t) /*where T : struct*/ { }
public override void F1<T>(T? t) where T : class { }
}
Чтобы разрешить заметки для параметров типа, которые не ограничены ссылочными типами или типами значений, C#9 разрешает новое ограничение where T : default
.
class A2
{
public virtual void F2<T>(T? t) where T : struct { }
public virtual void F2<T>(T? t) { }
}
class B2 : A2
{
public override void F2<T>(T? t) /*where T : struct*/ { }
public override void F2<T>(T? t) where T : default { }
}
Это ошибка использовать ограничение default
в любом контексте, кроме переопределения метода или явной реализации.
Это ошибка использования ограничения default
, если соответствующий параметр типа в переопределенном или интерфейсном методе ограничен ссылочным типом или типом значения.
Совещания по дизайну
C# feature specifications