可空<int>与int? – 有什么区别?
显然Nullable<int>
和int?
价值相当。 有什么理由select一个吗?
Nullable<int> a = null; int? b = null; a == b; // this is true
没有不同。
int?
只是Nullable<int>
缩写,它本身就是Nullable<Int32>
缩写。
编译的代码将完全相同,无论你select使用哪一个。
这个?
表格只是整个types的简写。 个人喜好是select一个的唯一原因。
全部细节在这里 。
语法
T?
是Nullable<T>
简写,其中T
是一个值types。 这两种forms是可以互换的。
虽然我完全同意在大多数情况下他们是一样的,但是最近我遇到了一个情况,那就是两者之间有区别。 对于血淋淋的细节看到这个问题 ,但在这里给你一个快速的例子:
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 ';'
如果你对这个问题的确切原因感到好奇,我真的build议你检查已经链接的问题 ,但是最基本的问题是在一个is
(或者as
)运算符之后的parsing阶段,当我们面对一个?
令牌,我们检查下一个标记是否可以被解释为一元运算符( &
可以是一个),如果是这样的话:parsing器不关心?
令牌是一个types修饰符,它简单地使用它之前的types,并将parsing其余的,如果?
令牌是三元运算符(因此parsing将失败)。
那么,一般来说int?
和Nullable<int>
是可以互换的,当它们产生完全不同的结果时,由于分析器如何看你的代码,有一些特殊情况。
在使用代码优先的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生成器将在相应的数据库表中生成一个可为空的字段。
可空是genericstypes,但int? 不是。
有一些Nullable应该用于int的情况?
例如:在这里,你不能用intreplaceNullable ?
如何在不使用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; } } }