【发布时间】:2010-10-26 23:14:52
【问题描述】:
显然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> 的简写。
无论您选择使用哪一个,编译后的代码都将完全相同。
【讨论】:
虽然我完全同意在大多数情况下它们是相同的,但我最近遇到了一种情况,这两者之间存在 差异。 有关血腥细节,请参阅this question,但在这里给你一个简单的例子:
// compiles happily
void Test<T>(T a, bool b)
{
var test = a is Nullable<int> & b;
}
将Nullable<int> 更改为int?(仅此而已):
//does not compile
void Test<T>(T a, bool b)
{
var test = a is int? & b;
}
第二个版本给出以下错误消息:
error CS1003: Syntax error, ':' expected
error CS1525: Invalid expression term ';'
如果你对这其中的确切原因感到好奇,我真的建议你检查一下已经存在的linked question,但基本问题是在is(或as)运算符之后的解析阶段,当我们面对? 标记时,我们检查 next 标记 可以 是否被解释为一元运算符(& 可能是一个),如果是:解析器不'不关心 ? 标记是类型修饰符的可能性,它只是使用它之前的类型,并将解析其余部分,就好像 ? 标记是三元运算符一样(因此解析将失败)。
因此,虽然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。
& 是按位与,而&& 是逻辑运算符。例如,它逐位计算结果... (1 == 01 & 2 == 10... (1 & 2) == 0bool 重载的文档。它们是Boolean logical operators(& 代表bool)和Boolean conditional logical operators(&& 代表bool)。请注意这些小节中的第一个是如何明确命名为 logical 的。请记住,在 C# 中,bool 和数字类型之间没有转换(“强制转换”)!
【讨论】:
在使用代码优先实体框架 (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 不可能看到两者之间的区别。即使 EF 的人想以不同的方式对待他们,他们也做不到。
Nullable 是泛型类型,但 int? 不是。
在某些情况下应该使用 Nullable 而不是 int?
例如:这里你不能用 int? 替换 Nullable
如何在不使用 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>