回答:
?フォームは、完全な形のためだけの省略形です。個人の好みが、どちらか一方を選ぶ唯一の理由です。
詳細はこちら。
構文は次のとおり
T?の省略形ですNullable<T>、T値型です。2つの形式は交換可能です。
私は完全にほとんどの場合、それらが同じであることに同意しますがあったとき、私は最近、状況に出くわしたあるこれら二つの違いは。詳細については、この質問を参照してください。ただし、簡単な例をここに示します。
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>は互換性がありますが、パーサーがコードをどのように認識するかにより、完全に異なる結果を生成するいくつかのまれなケースがあります。
testは括弧で固定されているので、var test = (a is int?) & b;です。またして固定することができvar test = a is int? && b;、その与えられb、好むように奇妙に思える単純な値のパラメータ(評価の副作用なし)である&オーバー&&。
?は、が重要な文字です。
int?3項演算(var test = a is int? <return if true> : <return if false>)として解釈されるため、コンパイルされません。
boolオーバーロードについては、ドキュメントを参照してください。これらはブール論理演算子(&for bool)とブール条件論理演算子(&&for bool)です。これらのサブセクションの最初の部分が明らかにlogicalと名付けられていることに注意してください。C#では、bool数値型と数値型の間の変換(「キャスト」)はありません。
コードファーストの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可能なプロパティを生成します。
Nullable組み込みのを使用するとNullable<T>、EFが2つの違いを確認できないため、どこかに他の定義があることを示しています。EFの人々はそれらを別の方法で扱いたいと思っていても、できませんでした。
null可能はジェネリック型ですが、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;
}
}
}
Nullable<T>ことのNullable<int>