Câu hỏi Nullable so với int? - Có sự khác biệt nào không?


Hiển nhiên Nullable<int> và int? tương đương về giá trị. Có bất kỳ lý do nào để chọn cái khác không?

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

76
2017-10-26 23:14


gốc




Các câu trả lời:


Không khác nhau.

int? chỉ là viết tắt của Nullable<int>, chính nó là viết tắt của Nullable<Int32>.

Mã được biên dịch sẽ chính xác giống với mã bạn chọn để sử dụng.


113
2017-10-26 23:16



... trừ khi bạn đang sử dụng mã EF trước. Xem câu trả lời của tôi dưới đây. - Maciej
Thật không may có một số trường hợp góc khi điều này là không đúng sự thật. Xem này câu trả lời. - qqbenq


Các ? hình thức chỉ là một cách viết tắt cho loại đầy đủ. Sở thích cá nhân là lý do duy nhất để chọn một người khác.

Chi tiết đầy đủ đây.

Cú pháp T? là viết tắt của    Nullable<T>, Ở đâu T là một loại giá trị.   Hai hình thức có thể hoán đổi cho nhau.


20
2017-10-26 23:17



... hoặc khả năng đọc. - adrianbanks
@adrianbanks - chắc chắn - Steve Townsend


Trong khi tôi hoàn toàn đồng ý rằng trong hầu hết các trường hợp, chúng giống nhau, gần đây tôi đã gặp phải một tình huống, khi có  sự khác biệt giữa hai điều đó. Để biết chi tiết đẫm máu, hãy xem câu hỏi này, nhưng để cung cấp cho bạn một ví dụ nhanh ở đây:

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
}

Dòng đầu tiên cung cấp các thông báo lỗi sau:

error CS1003: Syntax error, ':' expected 
error CS1525: Invalid expression term ';'

Nếu bạn tò mò về lý do chính xác cho điều này, tôi thực sự khuyên bạn nên kiểm tra câu hỏi được liên kết, nhưng vấn đề cơ bản là trong giai đoạn phân tích cú pháp sau một is (hoặc một as), khi chúng ta đối mặt với ? mã thông báo chúng tôi kiểm tra xem kế tiếp mã thông báo có thể được hiểu là một toán tử đơn nhất (& có thể là một) và nếu có: trình phân tích cú pháp không quan tâm đến khả năng của ? token là một công cụ sửa đổi kiểu, nó chỉ đơn giản sử dụng kiểu trước nó, và sẽ phân tích phần còn lại như thể ? token là một toán tử ternary (do đó việc phân tích cú pháp sẽ thất bại).

Vì vậy, trong khi nói chung int? và Nullable<int> có thể hoán đổi cho nhau, có một số trường hợp góc khi chúng tạo ra các kết quả hoàn toàn khác nhau, vì cách trình phân tích cú pháp nhìn thấy mã của bạn.


16
2017-07-14 14:03



Trường hợp đầu tiên, test, được cố định bằng dấu ngoặc đơn, vì vậy var test = (a is int?) & b;. Cũng có thể được sửa với var test = a is int? && b;và cho rằng b là một tham số giá trị đơn giản (không có tác dụng phụ khi đánh giá) có vẻ lạ &kết thúc &&. - Jeppe Stig Nielsen
Trong cú pháp cụ thể đó, ? là một nhân vật chính. - Pete Garafano
Tôi chỉ cần thêm thông tin này ở đây, vì tôi cảm thấy nó có liên quan, vì nó đưa ra một sự khác biệt giữa hai hình thức, và chứng minh rằng nó không chỉ là cú pháp cú pháp - qqbenq
Jeppe đúng. Nó không biên dịch vì nó diễn giải int? như một hoạt động ba năm (var test = a is int? <return if true> : <return if false>), không phải là một int vô giá trị. - Levi Fuller
Ngoài ra @ Jeppe ... & là một bitwise VÀ && là toán tử logic. Ví dụ, nó đánh giá kết quả bit-cho-bit ... (<decimal> == <binary>) 1 == 01 & 2 == 10... (1 & 2) == 0 - Levi Fuller


Rõ ràng là có sự khác biệt giữa hai khi sử dụng thế hệ Entity Framework (EF) mã đầu tiên:

Khi thực thể của bạn chứa thuộc tính được khai báo như:

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

EF sẽ không tạo ra một thuộc tính nullable và bạn sẽ phải ép buộc bộ tạo ra để làm cho nó không có giá trị như sau:

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();
    }
}

Mặt khác, nếu bạn khai báo thực thể của mình như:

public class MyEntity
{
     public int? MyNullableInt { get; set; }
}

bộ tạo EF sẽ tạo thuộc tính nullable với trường nullable trong bảng cơ sở dữ liệu tương ứng.


4
2018-06-05 14:06



Điều đó thực sự không may. - siride
Điều đó cho thấy bạn có một số Nullable định nghĩa ở đâu đó, bởi vì với built-in Nullable<T>, EF không thể thấy sự khác biệt giữa hai. Ngay cả khi người dân EF muốn đối xử với họ khác đi, họ vẫn không thể. - hvd
Có ai xác nhận đây là trường hợp? (chỉ cần thận trọng một chút vì những lá phiếu tiêu cực) - RayLoveless
@RayL Không, đây không phải là trường hợp. Câu trả lời này là không chính xác và như hvd chỉ ra, không thể. - Shoe
Xem xét rằng mã EF được tạo ra bằng cách sử dụng các mẫu mã, điều này có thể thực tế là có thể. Câu trả lời của tôi dựa trên trải nghiệm của tôi và thay đổi mà tôi đề xuất đã khắc phục sự cố tôi gặp phải. Ngoài ra, có vẻ như một số người thấy rằng nó thực sự là trường hợp dựa trên các phiếu bầu. - Maciej


Nullable là loại chung, nhưng int? không phải là.

Có một số tình huống Nullable nên được sử dụng trên int?

ví dụ: ở đây bạn không thể thay thế Nullable với int? 

làm thế nào bạn có thể thay đổi mã dưới đây mà không cần sử dụng 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;
      }
   }
}

1
2017-07-30 23:32



private T? val hoạt động tốt. - johnnyRose
Điều gì có thể quan trọng nếu câu hỏi đã được hỏi về các loại chung chung, nhưng câu hỏi đã chỉ định int, vì vậy nó không Nullable<T> nó là Nullable<int> - Andrew