Мабуть Nullable<int>і int?еквівалентні за вартістю. Чи є причини вибирати одне над іншим?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Мабуть Nullable<int>і int?еквівалентні за вартістю. Чи є причини вибирати одне над іншим?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Відповіді:
?Форма просто скорочення для повного типу. Особисті переваги - це єдина причина вибирати одне над іншим.
Повна інформація тут .
Синтаксис
T?є скороченим словомNullable<T>, деTє тип значення. Ці дві форми взаємозамінні.
Хоча я повністю згоден з тим, що в більшості випадків вони однакові, нещодавно я зіткнувся з ситуацією, коли між цими двома є різниця. Докладні відомості див. У цьому питанні , але щоб навести вам короткий приклад тут:
void Test<T>(T a, bool b)
{
var test = a is int? & b; // does not compile
var test2 = a is Nullable<int> & b; // does compile
}
Перший рядок містить такі повідомлення про помилки:
error CS1003: Syntax error, ':' expected
error CS1525: Invalid expression term ';'
Якщо вас цікавить точна причина цього, я справді рекомендую вам перевірити вже пов'язане питання , але основна проблема полягає в тому, що на етапі синтаксичного аналізу після оператора is(або as) оператора, коли ми стикаємося з ?маркером, ми перевіряємо, чи буде наступним маркер можна інтерпретувати як одинарний оператор ( &може бути і одним), і якщо так: синтаксичний аналізатор не дбає про можливість того, щоб ?маркер був модифікатором типу, він просто використовує тип перед ним, а решту аналізуватиме так, ніби ?лексеми були потрійним оператором (таким чином, аналіз не вдасться).
Отже, хоча загалом int?і Nullable<int>є взаємозамінними, є деякі кутові випадки, коли вони дають абсолютно різні результати, через те, як парсер бачить ваш код.
test,, фіксується в дужках, так var test = (a is int?) & b;. Можна також виправити за допомогою var test = a is int? && b;, а враховуючи, що bце простий параметр значення (відсутність побічних ефектів при оцінці), здається дивним віддавати перевагу &над &&.
?є ключовим символом.
int?як потрійна операція ( var test = a is int? <return if true> : <return if false>), а не як нульовий int.
boolперевантажень. Це логічні логічні оператори ( &for bool) та логічні умовні логічні оператори ( &&for bool). Зверніть увагу, як перший із цих підрозділів чітко названий логічним . Пам'ятайте, що в C # немає перетворень ("приводів") між boolі числовими типами!
Очевидно, між цими двома різницями є використання генерації Entity Framework (EF):
Коли ваша сутність містить властивість, заявлену як:
public class MyEntity
{
public Nullable<int> MyNullableInt { get; set; }
}
EF не генерує властивості, що дозволяють опустити, і вам доведеться змусити генератор зробити його таким чином:
public class YourContext : DbContext
{
public DbSet<MyEntity> MyEntities{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyEntity>().Property(x => x.MyNullableInt).IsOptional();
}
}
З іншого боку, якщо ви оголосите свою сутність як:
public class MyEntity
{
public int? MyNullableInt { get; set; }
}
генератор EF генерує властивість, що допускає нульове значення з полем, що допускає нульове значення у відповідній таблиці бази даних.
Nullableвизначення, оскільки завдяки вбудованому Nullable<T>EF не може побачити різницю між ними. Навіть якби люди з ЕФ хотіли поводитися з ними інакше, вони не могли.
Nullable - це загальний тип, але int? не.
Є кілька сценаріїв, коли Nullable слід використовувати над int?
наприклад: тут ви не можете замінити Nullable на int?
як ви можете змінити наведений нижче код без використання Nullable ?
class LazyValue<T> where T : struct
{
private Nullable<T> val;
private Func<T> getValue;
// Constructor.
public LazyValue(Func<T> func)
{
val = null;
getValue = func;
}
public T Value
{
get
{
if (val == null)
// Execute the delegate.
val = getValue();
return (T)val;
}
}
}
Nullable<T>такNullable<int>