Hướng dẫn là tất cả 0 (số không)?


241

Tôi đang thử nghiệm một số dịch vụ WCF gửi đối tượng với Hướng dẫn qua lại. Trong mã kiểm tra ứng dụng web của tôi, tôi đang làm như sau:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid()
});

Vì một số lý do, lệnh gọi tới Guid () mới đang tạo ra các Hướng dẫn với tất cả 0 (số không) như thế này:

00000000-0000-0000-0000-000000000000

Điều gì có thể gây ra điều này?


9
Sau khi chỉnh sửa, đây là một câu hỏi hoàn toàn mới. Và rất nhiều thông tin cần thiết để xác định câu trả lời mới.
Scott Rippey

3
Đã xóa phần chỉnh sửa đã thay đổi câu hỏi.
Didaxis

115
+1 vì tôi đã sử dụng câu hỏi này để ăn cắp một hướng dẫn trống hàng chục lần :)
jmosesman

5
@jmosesman, tốt hơn là sử dụng biểu mẫuGuid.Empty
Jonathan Moosekian

4
@JonathanM Tôi thực sự đang sử dụng nó trong tập lệnh SQL. Bài đăng này chỉ hiển thị đầu tiên sau khi tìm kiếm.
jmosesman

Câu trả lời:


428

Sử dụng phương thức tĩnh Guid.NewGuid()thay vì gọi hàm tạo mặc định.

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = Guid.NewGuid()
});

18
+1 cho câu trả lời đúng cũng như liên kết đến tài liệu phù hợp.
ObscureRobot

109

Bài học để học hỏi từ điều này:

1) Hướng dẫn là loại giá trị, không phải loại tham chiếu.

2) Gọi hàm tạo mặc định new S()trên bất kỳ loại giá trị nào luôn trả về cho bạn dạng hoàn toàn bằng không của loại giá trị đó, bất kể đó là gì. Nó là hợp lý như default(S).


3
Liệu nó có được biên dịch thành IL giống như default(S)hoặc có bất kỳ sự tinh tế nào mà tôi thiếu không?
cấu hình

8
@configurator: Có. Trong thực tế, biểu diễn bên trong của trình biên dịch "default (S)" và "new S ()" là như nhau; chúng tôi không phân biệt chúng trong nội bộ, điều này đã dẫn đến một số lỗi đáng tiếc trong những năm qua vì thực tế chúng không hoàn toàn giống nhau. Ví dụ, const int x = new int();không được coi là hợp pháp theo thông số kỹ thuật, nhưng const int x = default(int);là; chúng tôi cho phép cả hai.
Eric Lippert

1
@configurator - nếu bạn quan tâm đến các trường hợp góc liên quan, có lẽ msmvps.com/bloss/jon_skeet/archive/2008/12/10/ cũng sẽ được quan tâm.
kvb

56

Hãy thử điều này thay thế:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid.NewGuid()
});

Điều này sẽ tạo ra giá trị Hướng dẫn 'thực'. Khi bạn mới nhập loại tham chiếu, nó sẽ cung cấp cho bạn giá trị mặc định (trong trường hợp này là tất cả các số không cho Hướng dẫn).

Khi bạn tạo một Hướng dẫn mới, nó sẽ khởi tạo nó cho tất cả các số không, là giá trị mặc định cho Hướng dẫn. Về cơ bản, nó giống như việc tạo một int "mới" (là một loại giá trị nhưng bạn vẫn có thể thực hiện việc này):

Guid g1;                    // g1 is 00000000-0000-0000-0000-000000000000
Guid g2 = new Guid();       // g2 is 00000000-0000-0000-0000-000000000000
Guid g3 = default(Guid);    // g3 is 00000000-0000-0000-0000-000000000000
Guid g4 = Guid.NewGuid();   // g4 is not all zeroes

So sánh điều này với làm điều tương tự với một int:

int i1;                     // i1 is 0
int i2 = new int();         // i2 is 0
int i3 = default(int);      // i3 is 0

1
g1sẽ chỉ biên dịch dưới dạng trường và không phải là biến cục bộ. Ngoài ra, các chỉ số trong cột nhận xét của bạn không khớp với cùng một dòng mã
CodeInChaos

1
@CodeInChaos: Cảm ơn, đã sửa các bình luận. FYI, dòng g1 thực sự biên dịch ...
JohnD

3
Nó sẽ biên dịch như hiện tại, nhưng nó không có giá trị xác định. Nếu bạn thêm mã đọc nó (trước khi viết nó), nó sẽ không biên dịch nữa.
CodeInChaos

1
Đúng, điểm tốt, bạn sẽ gặp lỗi nếu bạn sử dụng biến chưa được khởi tạo, vì vậy giá trị không thể được sử dụng.
JohnD

1
bỏ phiếu vì dòng "Guid = Guid.NewGuid ();" có thể gây nhầm lẫn cho các nhà phát triển mới hơn. Xem xét chỉnh sửa thành một cái gì đó như "Guid someGuid = Guid.NewGuid ();" như dòng g2;)
daviesdoesit

25

Hãy thử làm:

Guid foo = Guid.NewGuid();

1
Lý do cho downvote: "Guid" là một loại nhưng được sử dụng như một biến.
daviesdoesit

19

Không thể cho bạn biết bao nhiêu lần điều này đã bắt được. tôi.

Guid myGuid = Guid.NewGuid(); 

11

Trong tinh thần hoàn thiện, các câu trả lời hướng dẫn bạn sử dụng Guid.NewGuid()là chính xác.

Để giải quyết chỉnh sửa tiếp theo của bạn, bạn sẽ cần đăng mã cho RequestObjectlớp của mình . Tôi nghi ngờ rằng tài sản hướng dẫn của bạn không được đánh dấu là a DataMember, và do đó không được nối tiếp qua dây. Vì default(Guid)giống như new Guid()(tức là tất cả 0), điều này sẽ giải thích hành vi bạn nhìn thấy.

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.