2008-09-16 27 views
47
EmployeeNumber = 
string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? null 
    : Convert.ToInt32(employeeNumberTextBox.Text), 

Tôi thường thấy mình muốn làm những việc như thế này (EmployeeNumberNullable<int> vì nó là thuộc tính trên đối tượng dbQ LINQ-to-SQL trong đó cột cho phép giá trị NULL). Thật không may, trình biên dịch cảm thấy rằng "Không có chuyển đổi tiềm ẩn giữa 'null' và 'int'", mặc dù cả hai loại sẽ hợp lệ trong một phép toán gán cho một int vô giá của riêng chúng.Phân bổ toán tử có điều kiện với các kiểu Nullable <value>?

Toán tử kết hợp song song không phải là một tùy chọn xa như tôi có thể thấy do chuyển đổi nội tuyến cần phải xảy ra trên chuỗi .Text nếu nó không phải là rỗng.

Theo như tôi biết, cách duy nhất để làm điều này là sử dụng câu lệnh if và/hoặc gán nó theo hai bước. Trong trường hợp cụ thể này tôi thấy rằng rất bực bội vì tôi muốn sử dụng cú pháp khởi tạo đối tượng và nhiệm vụ này sẽ nằm trong khối khởi tạo ...

Bất cứ ai biết một giải pháp thanh lịch hơn?

+1

Kiểm tra bài viết liên quan đến blog của Eric Lippert: [Gõ lời phàn nàn, phần một] (http://blogs.msdn.com/ericlippert/archive/2006/05/24/type-inference-woes-part -one.aspx) – CodesInChaos

+0

[Lỗi trình biên dịch ** CS0173 **] (http://msdn.microsoft.com/en-us/library/vstudio/hb47kt2f%28v=vs.120%29.aspx) đưa tôi đến đây. – DavidRR

Trả lời

60

Vấn đề xảy ra bởi vì các nhà điều hành có điều kiện không nhìn vào cách các giá trị được sử dụng (giao trong trường hợp này) để xác định loại của biểu thức - - chỉ các giá trị đúng/sai. Trong trường hợp này, bạn có một rỗng và một Int32, và loại không thể được xác định (có những lý do thực sự nó không thể chỉ là giả định Nullable <Int32>).

Nếu bạn thực sự muốn sử dụng nó theo cách này, bạn phải ép một trong các giá trị để Nullable <Int32> chính mình, do đó, C# có thể giải quyết các loại:

EmployeeNumber = 
    string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? (int?)null 
    : Convert.ToInt32(employeeNumberTextBox.Text), 

hoặc

EmployeeNumber = 
    string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? null 
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text), 
+4

Bạn cũng có thể viết 'int mới?()'. – SLaks

+6

Bạn nói có những lý do thực sự nó không thể giả định Nullable . Lý do gì? – BlueMonkMN

+1

@SLaks Hoặc 'mặc định (int?)'. – IllidanS4

3

Bạn có thể đúc đầu ra của Chuyển đổi:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? null 
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text) 
8

Tôi nghĩ rằng một phương pháp tiện ích có thể giúp làm sạch hơn.

public static class Convert 
{ 
    public static T? To<T>(string value, Converter<string, T> converter) where T: struct 
    { 
     return string.IsNullOrEmpty(value) ? null : (T?)converter(value); 
    } 
} 

sau đó

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse); 
+0

Đó là một ý tưởng thực sự hay, và một ví dụ về các phương pháp chung và mở rộng cực kì tuyệt vời :) – Grank

6

Trong khi Alex cung cấp câu trả lời đúng và gần cho câu hỏi của bạn, tôi thích sử dụng TryParse:

int value; 
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value) 
    ? (int?)value 
    : null; 

Đó là an toàn và chăm sóc các trường hợp đầu vào không hợp lệ cũng như kịch bản chuỗi trống của bạn. Nếu không, nếu người dùng nhập vào một cái gì đó như 1b, họ sẽ được trình bày một trang lỗi với ngoại lệ chưa được giải quyết gây ra trong Convert.ToInt32(string).

+0

Tôi thích xác thực đầu vào của người dùng bằng cách sử dụng ASP.NET CompareValidator, có thể được đặt thành Toán tử của DataTypeCheck và Kiểu int . Điều này đảm bảo rằng đầu vào sẽ không bao giờ là bất cứ điều gì khác hơn là một số nguyên, và hiện nó phía khách hàng nếu nó có thể. – Grank

1
//Some operation to populate Posid.I am not interested in zero or null 
int? Posid = SvcClient.GetHolidayCount(xDateFrom.Value.Date,xDateTo.Value.Date).Response; 
var x1 = (Posid.HasValue && Posid.Value > 0) ? (int?)Posid.Value : null; 

EDIT: lời giải thích ngắn gọn về ở trên, tôi đã cố gắng để có được giá trị của Posid (nếu nonnull nó int và có giá trị lớn hơn 0) trong varibale X1. Tôi đã phải sử dụng (int?) trên Posid.Value để có được toán tử có điều kiện không ném bất kỳ lỗi biên dịch nào. Chỉ một FYI GetHolidayCount là phương pháp WCF có thể cung cấp null hoặc bất kỳ số nào. Hy vọng rằng sẽ giúp

+0

Thông thường, bạn nên bao gồm mô tả về mã của bạn thay vì chỉ đăng mã. Điều này giúp người đặt câu hỏi (và những người đã tìm thấy câu hỏi này trong khi gặp phải vấn đề tương tự) hiểu những gì giải pháp của bạn đang làm. –

+0

Cảm ơn Robert đã chỉ ra điều đó. – Sandeep

Các vấn đề liên quan