По-видимому, 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
Никакой разницы.
int?
является просто сокращением для Nullable<int>
, который сам является сокращением для Nullable<Int32>
.
Скомпилированный код будет точно таким же, какой вы хотите использовать.
Форма ?
является просто сокращением для полного типа. Личные предпочтения - единственная причина выбора одного над другим.
Подробнее здесь.
Синтаксис
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 ';'
Если вам интересно узнать точную причину этого, я действительно рекомендую вам проверить уже связанный вопрос , но основная проблема заключается в том, что в фазе разбора после a is
(или as
), когда мы сталкиваемся с токеном ?
, мы проверяем, может ли следующий токен интерпретироваться как унарный оператор (&
может быть одним), и если это так: синтаксический анализатор doesn ' не заботьтесь о возможности того, что токен ?
является модификатором типа, он просто использует тип перед ним и будет анализировать остальные, как если бы токен ?
был тройным оператором (при этом синтаксический разбор не будет выполнен).
Итак, хотя в целом int?
и Nullable<int>
взаимозаменяемы, есть некоторые угловые случаи, когда они дают совершенно разные результаты из-за того, как парсер видит ваш код.
По-видимому, существует разница между ними при использовании генерации Entity Framework (EF) с кодовым первым:
Когда ваш объект содержит объявленное свойство:
public class MyEntity
{
public Nullable<int> MyNullableInt { get; set; }
}
EF не будет генерировать свойство nullable, и вам придется заставить генератор сделать его нулевым следующим образом:
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 - это общий тип, но 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;
}
}
}