Nullable <int>与int?-有什么区别吗?


Answers:


134

没有不同。

int?只是简写Nullable<int>,本身就是简写Nullable<Int32>

无论您选择使用哪一种,编译后的代码都将完全相同。


1
不幸的是,在某些极端情况下,这并非完全正确。看到这个答案
qqbenq 2014年

22

?表格只是完整类型的简写。个人喜好是唯一选择一个的唯一原因。

详细信息在这里

语法T?是的简写 Nullable<T>,其中T是值类型。两种形式可以互换。


18

尽管我完全同意在大多数情况下它们是相同的,但最近我遇到了一种情况,两者之间存在差异。有关gory的详细信息,请参见此问题,但在此处为您提供一个简单的示例:

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>是可以互换的,也有一些角落情况下,当它们产生完全不同的结果,因为分析器是如何看待你的代码。


2
第一种情况test用括号固定,因此var test = (a is int?) & b;。也可以固定var test = a is int? && b;,而且考虑到b是一个简单的参数值(在评估没有副作用)我觉得奇怪,喜欢&&&
Jeppe Stig Nielsen 2014年

在该特定语法中,?是关键字符。
Pete Garafano 2014年

看到链接的问题和答案,您的评论都在那里解决了:)我只是在这里添加了此信息,因为我觉得这是相关的,因为它使两种形式之间有所不同,并证明它不仅是语法糖
qqbenq 2014年

杰普是正确的。它不是编译的,因为它被解释int?为三元运算(var test = a is int? <return if true> : <return if false>),而不是可为null的int。
维·富勒

1
@LeviFuller (续)有关这些特殊的bool重载,请参见文档。它们是布尔逻辑运算符&for bool)和布尔条件逻辑运算符&&for bool)。请注意,这些小节中的第一个如何清楚地命名为逻辑。请记住,在C#中bool,数字类型之间没有转换(“转换”)!
Jeppe Stig Nielsen

6

使用代码优先实体框架(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生成器将通过属性生成一个可为空的属性,该属性在相应的数据库表中具有可为空的字段。


2
真是不幸。
siride

8
这表明您在Nullable某处还有其他定义,因为使用内置Nullable<T>,EF不可能看到两者之间的区别。即使EF员工想以不同的方式对待他们,他们也不会。

1
有人确认是这种情况吗?(由于投了反对票,所以要谨慎一点)
RayLoveless

@RayL不,不是这样。这个答案是不正确的,并且正如hvd指出的那样,这是不可能的。

1
考虑到EF代码是使用代码模板生成的,实际上这是可能的。我的答案基于我的经验,我建议进行更改可以解决我遇到的问题。另外,似乎有些人发现基于上投票确实是这种情况。
Maciej 2014年

2

Nullable是泛型类型,但是int吗?不是。

在某些情况下,应在int上使用Nullable

例如:在这里您不能用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;
      }
   }
}

2
如果这个问题是问泛型类型,但问题已经指定的int可能无所谓,所以它不是Nullable<T>它的Nullable<int>
安德鲁·
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.