2009-06-23 37 views
6

Làm thế nào để đúc một đối tượng (loại Object) vào loại thực của nó?Làm thế nào để đúc một đối tượng vào loại của nó?

tôi cần phải làm một số điều như kiểu này

Myobject [i] += Myobject [j]; 

MyObject là Object. Myobject [i] và myobject [j] sẽ luôn có cùng loại.

myObject [i] .Gettype() sẽ cung cấp cho tôi các loại ... nhưng làm thế nào tôi sẽ thực sự cast đối tượng vào loại đó để thực hiện '+' hành

+0

Mảng Myobject được khai báo là gì? – ChrisF

+0

Toán tử '+' được định nghĩa cho kiểu 'MyObject'? – Groo

+0

đối tượng [] Myobject –

Trả lời

16

Tôi giả định việc bổ sung (+) toán tử được định nghĩa cho loại tùy chỉnh của bạn (MyType trong ví dụ này).

Nếu có, bạn chỉ cần bỏ LHS và RHS của bài tập. Điều này là bắt buộc vì cả hai toán hạng phải là được biết đến các loại tại thời gian biên dịch để chọn quá tải toán tử chính xác. Đây là thứ được yêu cầu bởi ngôn ngữ tĩnh, mặc dù ngôn ngữ động (có thể là C# 4.0) có thể giải quyết vấn đề này.

((MyType)Myobject[i]) += (MyType)Myobject[j]; 

Cập nhật:

Một số phản ánh kỳ diệu có thể khắc phục vấn đề này trong C# 2.0/3.0 (với thiếu gõ động).

public static object Add(object a, object b) 
{ 
    var type = a.GetType(); 
    if (type != b.GetType()) 
     throw new ArgumentException("Operands are not of the same type."); 

    var op = type.GetMethod("op_Addition", BindingFlags.Static | BindingFlags.Public); 
    return op.Invoke(null, new object[] { a, b }); 
} 

Lưu ý rằng điều này chỉ làm việc cho loại phi nguyên thủy. Đối với các kiểu nguyên thủy như int, float, v.v., bạn sẽ cần thêm câu lệnh chuyển đổi trên loại tự đúc các toán hạng và áp dụng toán tử cộng. Điều này là do quá tải của toán tử không thực sự được định nghĩa cho các kiểu nguyên thủy mà được xây dựng trong CLR.

Dù sao, hy vọng sẽ giải quyết được vấn đề của bạn.

+0

Tôi không biết loại "MyType" tại thời gian biên dịch –

+1

Hmmm, điều đó làm phức tạp ... – Noldorin

+0

Xem câu trả lời cập nhật của tôi bài đăng của anh ấy. – Noldorin

1

Nếu Myobject là một mảng rồi

Myobject [i] += Myobject [j]; 

nên làm việc miễn là các nhà điều hành + đã được xác định cho các loại.

Như Myobject là loại đối tượng này sẽ thất bại với các lỗi:

Operator '+' cannot be applied to operands of type 'object' and 'object'

Để có được loại tại thời gian chạy (một ví dụ contrived):

double a = 1.0; 
double b = 2.0; 

object a1 = a; 
object b1 = b; 

Type ta = a1.GetType(); 
Type tb = b1.GetType(); 

tatb là thiết lập để " Gấp đôi".

UPDATE:

Một lời cảnh báo trước - những gì tôi sắp đề nghị là rất vô duyên (để nói rằng ít nhất)

Nếu bạn có một số hữu hạn các loại và là các loại đảm bảo giống nhau.Nếu bạn có thể làm như sau:

Type test = Myobject[i].GetType(); 
if (test.Equals(typeof(double))) 
{ 
    (double)Myobject[i] += (double)Myobject[j]; 
} 

v.v.

Nếu các loại không giống nhau thì phức tạp hơn một chút.

Nếu bạn đã có một số không rõ các loại sau đó bạn sẽ cần phải chờ cho C# 4.

Hoặc bạn có thể làm với suy nghĩ như Noldorin gợi ý.

8

Loại có biết tại thời gian biên dịch không?

C# không (cho đến khi C# 4.0) hỗ trợ các toán tử trên mọi thứ ngoại trừ các loại cố định, đã biết.

Bạn có thể sử dụng toán tử với generics qua một vài thủ thuật - like so. Hãy cho tôi biết nếu Generics là một yếu tố ở đây (tôi có thể nói chuyện dài dòng về vấn đề này ...)

Trong 4.0, bạn có thể sử dụng:

dynamic x = MyObject[i]; 
x += MyObject[j]; 
MyObject[i] = x; 

Việc sử dụng dynamic gây ra rất nhiều kỳ diệu xảy ra ;-p

Khác với hai trường hợp đó, bạn cần phải biết loại của chúng tại thời điểm biên dịch hoặc thực hiện công việc.

+0

Phép thuật là thứ giữ cho thế giới quay tròn. –

+0

Loại sẽ là loại số. nó có thể là phao, gấp đôi, số nguyên hoặc bất kỳ thứ gì –

+0

Mà không thay đổi bất cứ điều gì, thật không may. Các "generics" lừa có lẽ là đặt cược tốt nhất của bạn, nhưng điều đó đòi hỏi một mảng loại. Bạn có thể sử dụng MakeGenericMethod để chuyển từ 'object' sang mã toán tử chung, nhưng nó sẽ không đẹp. Và MakeGenericMethod là chậm ('năng động' sẽ tốt hơn, khi được phát hành). –

0

Tốt hơn hết là tránh đấm bốc và unboxing và sử dụng các loại trực tiếp. Tôi không biết tất cả các nền của bạn, nhưng có lẽ nó là tốt hơn để chuyển đổi mảng để loại thực, hoặc sử dụng danh sách chung chung?

MyType[] array = new MyType[x]; 

hoặc

List<MyType> list = new List<MyType>(); 
0

Tôi sẽ đề nghị sử dụng một tuyên bố swicth, như các loại sẽ là một số. Trên mỗi chi nhánh, bạn có thể cast số của bạn để biến tạm thời và thực hiện các hoạt động như:

switch (Myobjetc[j].GetType()) 
    { 
     case typeof(short):     
      break; 
     case typeof(int): 
      int a, b = 0; 
      a = (int)Myobjet[i]; 
      b = (int)Myobject[j]; 
      a += b; 
      break; 
     case typeof(long): 
      break; 
     case typeof(decimal): 
      break; 
     case typeof(double): 
      break; 
     case typeof(float): 
      break;    
     default: 
      break; 
    } 
+2

Ngoại trừ nút chuyển đó (obj.GetType()) không biên dịch - "Giá trị của loại tích phân dự kiến ​​" – ChrisF

+0

thay thế 'chuyển đổi' bằng 'if' sẽ làm ... yêu cầu một số công việc (và thử nghiệm) mặc dù –

+0

obj.GetType() đề cập đến Myobject [j]/Myobject [i], chỉ để viết nhanh hơn một chút. Tôi sẽ chỉnh sửa ngay bây giờ. –

0

Một giải pháp tốt hơn cho các kiểu dữ liệu mà không đòi hỏi một câu lệnh switch là như thế này: (VB.Net)

Private Shared AddT As Func(Of T, T, T) 
If AddT = Nothing Then 
    Dim paramX As Expressions.ParameterExpression = Expressions.Expression.Parameter(GetType(T), "x") 
    Dim paramY As Expressions.ParameterExpression = Expressions.Expression.Parameter(GetType(T), "y") 
    Dim body As Expressions.BinaryExpression = Expressions.Expression.AddChecked(paramX, paramY) 
    Matrix(Of T).AddT = Expressions.Expression.Lambda(Of Func(Of T, T, T))(body, paramX, paramY).Compile 
End If 
Private a as MyType 
Private b as MyType 
AddT(a,b) 'instead of a+b 

Các giải pháp nhân, chia, v.v ... tương tự. Hy vọng rằng chuyển đổi ở trên để C# sẽ không quá đau đớn! Điều quan trọng là AddT được chia sẻ (tĩnh) vì biên dịch lại biểu thức lambda mỗi lần sẽ lãng phí các chu kỳ đồng hồ. Quá tệ. Net không có "MyType implement {+, -, *, etc}"!

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