2010-04-21 2 views
10

Я пишу обертку C# для сторонней библиотеки, которая считывает как одиночные значения, так и массивы с аппаратного устройства, но всегда возвращает массив объекта [] даже для одного значения. Для этого требуется повторный вызов объекта [0], когда я хочу, чтобы конечный пользователь мог использовать генерики для получения массива или одного значения.C# generics, когда T может быть массивом

Я хочу использовать дженерики так вызываемая можно использовать обертку следующими способами:

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[]; 

В MyWrapper У меня есть свойство Value в настоящее время в следующем:

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'

Если изменить MyWrapper.Value Т [] Я получаю:

Невозможно преобразовать тип 'объект []' на 'T []'

Любые идеи о том, как для достижения моей цели? Благодаря!

+0

Как определяется _wrappedObject? –

+0

_wrappedObject определяется с помощью MyWrapper. Он принимает параметр arraySize. Для шаблонов без массивов я передаю значение 1 для этого значения. – bufferz

ответ

9

Edit: Обновленный ответ. Библиотека возвращает массив объектов, вы не сможете просто вернуть его в виде T, будь то массив или один элемент, не выполняя некоторую работу с ним. Нижеприведенная функция представляет собой пример взятия массива объектов и возврата его как массива или одного элемента.

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 
    } 
} 

Пример потребляющих его:

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

Помните, что T сам массив в этих обстоятельствах, т. е. T [] будет представлять массив массивов. Поэтому мне еще нужно вернуть только T not T []. Я надеюсь, что в этом есть смысл. Спасибо за помощь! – bufferz

+0

Исходный код, предназначенный для T к типу элемента, а не к типу массива. На основе T вы получите массив T. Однако я обновил код с помощью функции, которая определит, является ли T массивом и действует соответственно. –

+0

Это точно то, что я искал! Большое спасибо Энтони !!!! – bufferz

2

Вы должны обмануть компилятор литья вашего массива в объект первого

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

Это компилируется, однако помните, что T является массивом в этих обстоятельствах. So (T) (object) _wrappedObject.Value throws и exception «Невозможно передать объект типа« System.Object [] »для ввода« System.Single [] », когда T является float [] – bufferz

Смежные вопросы