2010-04-21 36 views
10

Tôi đang viết C# wrapper cho thư viện của bên thứ ba đọc cả giá trị và mảng đơn từ thiết bị phần cứng, nhưng luôn trả về mảng object [] ngay cả đối với một giá trị. Điều này đòi hỏi lặp đi lặp lại các cuộc gọi đến đối tượng [0] khi tôi muốn người dùng cuối có thể sử dụng Generics để nhận một mảng hoặc một giá trị đơn.C# generics khi T có thể là một mảng

Tôi muốn sử dụng Generics để callee có thể sử dụng các wrapper trong các cách sau:

MyWrapper<float> mw = new MyWrapper<float>(...); 
float value = mw.Value; //should return float; 

MyWrapper<float[]> mw = new MyWrapper<float[]>(...); 
float[] values = mw.Value; //should return float[]; 

Trong MyWrapper Tôi có tài sản giá trị gia tăng hiện như sau:

public T Value 
{ 
    get 
    { 
     if(_wrappedObject.Values.Length > 1) 
     return (T)_wrappedObject.Value; //T could be float[]. this doesn't compile. 
     else 
     return (T)_wrappedObject.Values[0]; //T could be float. this compiles. 
    } 
} 

tôi nhận được một biên dịch lỗi trong trường hợp đầu tiên:

Không thể chuyển đổi loại 'đối tượng []' sang 'T'

Nếu tôi thay đổi MyWrapper.Value để T [] Tôi nhận:

Không thể chuyển đổi loại 'object []' thành 'T []'

Bất kỳ ý tưởng về cách để đạt được mục tiêu của tôi? Cảm ơn!

+0

như thế nào _wrappedObject được xác định? –

+0

_wrappedObject được định nghĩa với MyWrapper được tạo. Phải có tham số arraySize. Đối với các mẫu không mảng, tôi chuyển vào 1 cho giá trị này. – bufferz

Trả lời

9

Edit: Cập nhật câu trả lời. Thư viện đang trả về một mảng đối tượng, bạn sẽ không thể đơn giản trả về nó như T, có thể là một mảng hay một phần tử đơn lẻ, mà không làm việc với nó. Hàm dưới đây là một ví dụ về việc lấy một mảng các đối tượng và trả về nó như một mảng hoặc một phần tử đơn lẻ.

public static T GetValue<T>(object[] inputs) 
{ 
    if (typeof(T).IsArray) 
    { 
     Type elementType = typeof(T).GetElementType(); 
     Array array = Array.CreateInstance(elementType, inputs.Length); 
     inputs.CopyTo(array, 0); 
     T obj = (T)(object)array; 
     return obj; 
    } 
    else 
    { 
     return (T)inputs[0]; 
     // will throw on 0-length array, check for length == 0 and return default(T) 
     // if do not want exception 
    } 
} 

Ví dụ về tiêu thụ nó:

object[] inputs = { 1f, 2f, 3f }; // what the library is returning 
float[] array = GetValue<float[]>(inputs); // what you want? 
float singleValue = GetValue<float>(inputs); // what you want? 
+0

Hãy nhớ rằng T là chính nó một mảng trong các trường hợp này, tức là T [] sẽ đại diện cho một mảng các mảng. Vì vậy, tôi vẫn cần phải trả lại chỉ T không T []. Tôi hy vọng điều đó đúng. Cảm ơn đã giúp đỡ! – bufferz

+0

Mã ban đầu dành cho T cho loại phần tử, không phải kiểu mảng. Dựa trên T, bạn sẽ nhận được một mảng T. Tuy nhiên, tôi đã cập nhật mã với một hàm sẽ xác định nếu T là một mảng và hành động tương ứng. –

+0

Điều này đã làm chính xác những gì tôi đang tìm kiếm! Cảm ơn rất nhiều Anthony !!!! – bufferz

2

Bạn cần phải đánh lừa trình biên dịch bằng cách đúc mảng của bạn thành một đối tượng đầu tiên

public T Value 
{ 
    get 
    { 
     if(_wrappedObject.Values.Length > 1) 
     return (T)(object)_wrappedObject.Value; //T could be float[]. this doesn't compile. 
     else 
     return (T)_wrappedObject.Values[0]; //T could be float. this compiles. 
    } 
} 
+0

Biên dịch này, tuy nhiên hãy nhớ rằng T là một mảng trong các trường hợp này. Vì vậy, (T) (đối tượng) _wrappedObject.Value ném và ngoại lệ "Không thể đúc đối tượng của loại 'System.Object []' để gõ 'System.Single []'" khi T là một phao [] – bufferz

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