Mục đích của một dấu hỏi sau một loại (ví dụ: int? MyVariable) là gì?


433

Thông thường, việc sử dụng chính của dấu hỏi là dành cho điều kiện , x ? "yes" : "no".

Nhưng tôi đã thấy một cách sử dụng khác cho nó nhưng không thể tìm thấy lời giải thích về việc sử dụng ?toán tử này, chẳng hạn.

public int? myProperty
{
   get;
   set;
}

Câu trả lời:


436

Điều đó có nghĩa là loại giá trị trong câu hỏi là loại không thể

Các kiểu không thể là các thể hiện của cấu trúc System.Nullable. Một loại nullable có thể biểu thị phạm vi giá trị chính xác cho loại giá trị cơ bản của nó, cộng với một giá trị null bổ sung. Ví dụ: a Nullable<Int32>, phát âm là "Nullable of Int32", có thể được gán bất kỳ giá trị nào từ -2147483648 đến 2147483647 hoặc có thể được gán giá trị null. A Nullable<bool>có thể được gán các giá trị true, false hoặc null. Khả năng gán null cho các kiểu số và Boolean đặc biệt hữu ích khi bạn đang xử lý cơ sở dữ liệu và các loại dữ liệu khác có chứa các phần tử có thể không được gán một giá trị. Ví dụ: trường Boolean trong cơ sở dữ liệu có thể lưu trữ các giá trị đúng hoặc sai hoặc có thể không xác định.

class NullableExample
{
  static void Main()
  {
      int? num = null;

      // Is the HasValue property true?
      if (num.HasValue)
      {
          System.Console.WriteLine("num = " + num.Value);
      }
      else
      {
          System.Console.WriteLine("num = Null");
      }

      // y is set to zero
      int y = num.GetValueOrDefault();

      // num.Value throws an InvalidOperationException if num.HasValue is false
      try
      {
          y = num.Value;
      }
      catch (System.InvalidOperationException e)
      {
          System.Console.WriteLine(e.Message);
      }
  }
}

3
Được sử dụng cho struct. Đừng nghĩ rằng nó thực sự hữu ích cho các lớp học.
MonsieurDart

8
@MonsieurDart - đó là lý do tại sao câu trả lời nói "loại giá trị"
Sean

3
@AntoineDahan - các loại giá trị không có loại nullable vì chúng theo định nghĩa không nullable. Tôi nghĩ rằng bạn đang nghĩ về Java, nơi có một intloại và một Integerlớp tương ứng , ví dụ.
Sean

2
tài liệu gần đây hơn (2015) cho loại không có giá trị ở đây
khủng long


118

Nó là một tốc ký cho Nullable<int>. Nullable<T>được sử dụng để cho phép một loại giá trị được đặt thành null. Các loại giá trị thường không thể là null .


3
cộng với một để sử dụng thuật ngữ tốc ký, Khá thẳng về phía trước!
Hari

3
Câu thứ hai làm tôi bối rối. Bạn có ý nghĩa gì bởi "không thể"? Ở cấp độ trình biên dịch hoặc trong bối cảnh ứng dụng.
vấn đề

5
@pro Hiệuofficer theo định nghĩa, value typeskhông thể rỗng. Nếu bạn khai báo một int hoặc bool (là các loại giá trị) mà không chỉ định cụ thể một giá trị, thì chúng vẫn sẽ có các giá trị (0 và false, tương ứng), tức là. họ sẽ không có giá trị reference typesMặt khác, không được gán , chẳng hạn như đối tượng hoặc MyClass, sẽ là null. Bạn có thể muốn đọc về sự khác biệt giữa các loại giá trị và loại tham chiếu.
Klaus Byskov Pedersen

Cám ơn vì đã giải thích. Giờ thì tôi đã hiểu.
vấn đề

62

Trong

x ? "yes" : "no"

cái gì? tuyên bố một câu nếu . Ở đây: x đại diện cho điều kiện boolean; Phần trước câu : là câu sau đó và phần sau là câu khác .

Trong, ví dụ,

int?

cái gì? khai báo một loại nullable và có nghĩa là loại trước nó có thể có giá trị null.


9
Tôi không thấy bất kỳ mối quan hệ nào giữa '?' khai báo một loại không có khả năng và một biểu thức ternary. Bỏ phiếu trả lời của bạn xuống thưa ông.
Gus Crawford

36
Tôi không đồng ý với nhận xét trên từ Gus. Câu hỏi cho thấy có một sự nhầm lẫn có thể xảy ra với biểu thức ternary. Câu trả lời này giải quyết vấn đề này.
Mario Levesque

Bạn sẽ sử dụng loại so sánh null này ở đâu? Bên trong một sự trở lại dường như không được phép. return value ? value : "isNull";nói với tôi rằng string valuekhông thể chuyển đổi thành bool.
C4d

Tôi phải nói rằng đây là một câu trả lời rất phức tạp, đặc biệt là khi so sánh với những người khác về câu hỏi này .. -1
FastTrack

Đây phải là câu trả lời được chấp nhận. Vì nó rõ ràng và chính xác. +1
JP Dolocanog

49

Các loại không thể

Các kiểu không thể là các thể hiện của cấu trúc System.Nullable. Một loại nullable có thể biểu thị phạm vi giá trị bình thường cho loại giá trị cơ bản của nó, cộng với một giá trị null bổ sung . Ví dụ: [ Nullable<Int32>], được phát âm là "Nullable of Int32", có thể được gán bất kỳ giá trị nào từ -2147483648 đến 2147483647 hoặc có thể được gán giá trị null. Một [ Nullable<bool>] có thể được gán các giá trị đúng hoặc sai hoặc null. Khả năng gán null cho các kiểu số và Boolean đặc biệt hữu ích khi xử lý cơ sở dữ liệu và các loại dữ liệu khác có chứa các phần tử có thể không được gán một giá trị. Ví dụ: trường Boolean trong cơ sở dữ liệu có thể lưu trữ các giá trị đúng hoặc sai hoặc có thể không xác định.


11

Nó tuyên bố rằng loại này là nullable.


2
Mục nhập đầu tiên của bạn không có ý nghĩa, đưa ra mẫu người hỏi.
Nhị phân nhị phân

Chỉ tò mò về đánh giá khi tất cả các câu trả lời sâu ở trên :)
Naga

6

sử dụng thực tế:

public string someFunctionThatMayBeCalledWithNullAndReturnsString(int? value)
{
  if (value == null)
  {
    return "bad value";
  }

  return someFunctionThatHandlesIntAndReturnsString(value);
}

1
Trong khi OP vẫn hoạt động, 5 năm sau khi câu hỏi được hỏi, câu trả lời có thể không còn phù hợp nữa.
Dâu

10
với tôi đó là 3 giờ trước :-)
AJBauer

3

Để thêm vào các câu trả lời ở trên, đây là một mẫu mã

struct Test
{
    int something;
}
struct NullableTest
{
    int something;
}
class Example
{
    public void Demo()
    {
        Test t = new Test();
        t = null;

        NullableTest? t2 = new NullableTest();
        t2 = null;
    }
}

Điều này sẽ cung cấp một lỗi biên dịch:

Lỗi 12 Không thể chuyển đổi null thành 'Kiểm tra' vì đây là loại giá trị không thể rỗng

Lưu ý rằng không có lỗi biên dịch cho NullableTest. (lưu ý? trong phần khai báo của t2)


2

int?là tốc ký cho Nullable<int>. Hai hình thức có thể thay thế cho nhau.

Nullable<T>là một toán tử mà bạn có thể sử dụng với một loại giá trị Tđể làm cho nó chấp nhận null.

Trong trường hợp bạn không biết nó: giá trị loại là loại chấp nhận các giá trị như int, bool, charvv ...

Họ không thể chấp nhận tham chiếu đến các giá trị: họ sẽ tạo ra lỗi thời gian biên dịch nếu bạn gán cho họ một null, trái ngược với các loại tham chiếu , rõ ràng có thể chấp nhận nó.

Tại sao bạn cần điều đó? Bởi vì đôi khi các biến loại giá trị của bạn có thể nhận được các tham chiếu null được trả về bởi thứ gì đó không hoạt động tốt, như biến bị thiếu hoặc không xác định được trả về từ cơ sở dữ liệu.

Tôi khuyên bạn nên đọc Tài liệu Microsoft vì nó bao quát chủ đề khá tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.