Nullable <int>対int?-違いはありますか?


93

どうやらNullable<int>およびint?値に相当します。どちらか一方を選択する理由はありますか?

Nullable<int> a = null;
int? b = null;
a == b; // this is true

回答:


134

変わりはない。

int?はの省略形でありNullable<int>、それ自体がの省略形ですNullable<Int32>

コンパイルされたコードは、どちらを使用する場合でもまったく同じです。


1
残念ながら、これが厳密に当てはまらない場合があります。この回答を参照してください。
qqbenq

22

?フォームは、完全な形のためだけの省略形です。個人の好みが、どちらか一方を選ぶ唯一の理由です。

詳細はこちら

構文は次のとおりT?の省略形です Nullable<T>T値型です。2つの形式は交換可能です。


18

私は完全にほとんどの場合、それらが同じであることに同意しますがあったとき、私は最近、状況に出くわしたあるこれら二つの違いは。詳細については、この質問を参照してください。ただし、簡単な例をここに示します。

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)演算子の後の解析フェーズで、?トークンに直面したときに次のトークン単項演算子(&1の可能性があり?ます)として解釈できます。その場合、パーサーはトークンが型修飾子である可能性を考慮せず、単純にその前の型を使用し、残りを次のように解析します?トークンは三項演算子でした(したがって、解析は失敗します)。

したがって、一般的int?Nullable<int>は互換性がありますが、パーサーがコードをどのように認識するかにより、完全に異なる結果を生成するいくつかのまれなケースがあります。


2
最初のケースtestは括弧で固定されているので、var test = (a is int?) & b;です。またして固定することができvar test = a is int? && b;、その与えられb、好むように奇妙に思える単純な値のパラメータ(評価の副作用なし)である&オーバー&&
Jeppe Stig Nielsen

その特定の構文で?は、が重要な文字です。
ピートガラファノ2014

リンクされた質問と回答を参照してください。あなたのコメントはすべてそこで処理されます:)この情報をここに追加しました。これは、2つの形式の違いを引き出し、それが構文上の糖ではないことを証明しているため、関連があると感じたためです
qqbenq

ジェップは正しいです。null許容のintではなく、int?3項演算(var test = a is int? <return if true> : <return if false>)として解釈されるため、コンパイルされません。
Levi Fuller

1
@LeviFuller (続き)これらの特定のboolオーバーロードについては、ドキュメントを参照してください。これらはブール論理演算子&for bool)とブール条件論理演算子&&for bool)です。これらのサブセクションの最初の部分が明らかにlogicalと名付けられていることに注意してください。C#では、bool数値型と数値型の間の変換(「キャスト」)はありません。
Jeppe Stig Nielsen

6

コードファーストのEntity Framework(EF)生成を使用する場合、2つの間に明らかに違いがあります。

エンティティに次のように宣言されたプロパティが含まれている場合:

public class MyEntity
{
    public Nullable<int> MyNullableInt { get; set; } 
}

EFはnull可能プロパティを生成しないため、次のようにジェネレーターを強制的にnull可能にする必要があります。

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ジェネレーターは、対応するデータベーステーブルにnull可能なフィールドを持つnull可能なプロパティを生成します。


2
それは本当に残念です。
シリド2013年

8
Nullable組み込みのを使用するとNullable<T>、EFが2つの違いを確認できないため、どこかに他の定義があることを示しています。EFの人々はそれらを別の方法で扱いたいと思っていても、できませんでした。

1
これが事実であることを誰かが確認しましたか?(
反対

@RayLいいえ、そうではありません。この答えは正しくなく、hvdが指摘したように、不可能です。

1
コードテンプレートを使用してEFコードが生成されることを考えると、これは実際に可能である可能性があります。私の答えは私の経験と私が提案した変更が私が抱えていた問題を修正したことに基づいています。また、一部の人々は、それが実際に賛成票に基づくケースであることを発見したようです。
Maciej 2014年

2

null可能はジェネリック型ですが、int?ではありません。

Nullableintで使用する必要があるいくつかのシナリオがありますか

たとえば、ここではNullableintに置き換えることはできませんか?

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>
アンドリュー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.