2012-05-04 42 views
8

tôi có chức năng này:Toán tử có động C#?

static void Func1<T>(T x, T y) 
{ 
    dynamic result = ((dynamic)x + y); //line 1 
    dynamic result2 = (x + y);   //line 2 
} 

func này có thể được thực hiện như Func(1,2); Tuy nhiên, dòng 1 là OK, trong khi dòng 2 đi BANG (tại thời gian biên dịch).

Trường hợp ngoại lệ ném từ dòng 2 là:

Operator '+' không thể được áp dụng cho toán hạng kiểu 'T' và 'T'

Vì vậy, chúng ta cần tạo một nhà điều hành quá tải. Được rồi, cho đến nay rất tốt.

Nhưng còn dòng 1 thì sao? Không nên cần một dàn diễn viên năng động cũng trên y?

((dynamic)x + (dynamic)y);

Tôi hiểu rằng nó đang được đánh giá trong thời gian chạy, nhưng tại sao các biên dịch C# chấp nhận + nhà điều hành trong dòng 1 (ví dụ giả định sai T có thể được + đến cái gì khác)?

+0

Giá trị trong 'kết quả' sau khi thực thi mã là gì? Có phải '3' hay '12'. Tôi đoán là nó đang nối chuỗi. – Servy

+1

@Servy: Điều gì khiến bạn nghĩ rằng nó sẽ nối chuỗi khi 'T' là' int'? – LukeH

Trả lời

7

Trong ví dụ đầu tiên của bạn, bằng cách thực hiện x một dynamic bạn đã thực hiện cũng như hoạt động của hoạt động operator+. Điều này loại bỏ loại thông số T cho x, do đó loại bỏ khiếu nại rằng T không có giá trị operator+.

Lúc chạy động ràng buộc sẽ xảy ra và đánh giá hai toán hạng để đảm bảo rằng operator+ thể được sử dụng:

Nếu một toán hạng của một toán tử số học có loại thời gian biên dịch năng động, thì biểu thức bị ràng buộc động (§7.2.2). Trong trường hợp này, kiểu biên dịch của biểu thức là động và độ phân giải được mô tả bên dưới sẽ diễn ra vào thời gian chạy bằng cách sử dụng kiểu thời gian chạy của các toán hạng đó có kiểu động thời gian biên dịch.

Trong ví dụ thứ hai, trình biên dịch biết các loại cho x + y và chỉ lưu kết quả vào biến số dynamic. Các tập quán bổ sung của result2 sẽ bị ràng buộc động.Điều này làm cho cảm giác như không có hoạt động năng động với đúng của toán tử gán:

Khi không có biểu hiện động có liên quan, C mặc định # để tĩnh ràng buộc, có nghĩa là các loại thời gian biên dịch các biểu thức thành phần là được sử dụng trong quá trình lựa chọn.

+0

Plus, tôi phải tự hỏi tại sao bạn sẽ làm cho một phương pháp chung chung cố gắng sử dụng các toán tử kiểu cụ thể mà không có một ràng buộc. – Tejs

+0

Vâng, đối với một cái gì đó như kiểu số bạn không thể đến với bất kỳ ràng buộc loại nào mà sẽ cho phép các phép toán số học. – user7116

+0

Tôi nghĩ rằng cách ưa thích sẽ đơn giản là tạo ra tình trạng quá tải cho những loại giá trị cụ thể như khung làm việc. Nếu không, nếu bạn muốn có các loại cụ thể thực hiện một số loại hoạt động như vậy, hãy làm cho chúng triển khai một giao diện cụ thể và sau đó hạn chế giao diện đó. – Tejs

3

dynamic về cơ bản cho trình biên dịch "không cố gắng đảm bảo những gì tôi đang làm là hợp pháp; tôi chắc chắn nó sẽ có thời gian chạy". Bất kỳ thao tác nào bạn thử trên một biến động đều sẽ biên dịch. Nó sẽ không chạy thành công nếu kiểu được gán cho biến động không thực sự thực hiện thao tác. Đối với lý do tại sao cả hai người trong số họ không phải là năng động, trình biên dịch về cơ bản sẽ cố gắng tìm một nhà điều hành (phương pháp tĩnh) trên một trong các loại tham gia vào hoạt động phù hợp với chữ ký, bắt đầu với LValue. Với LValue là động, trình biên dịch phải giả định rằng hoạt động tồn tại trên bất cứ thứ gì sẽ được sử dụng như X, mặc dù X có cùng kiểu giữ chỗ như Y và Y không được biết là có toán tử +.