Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию 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