Я пишу обертку C# для сторонней библиотеки, которая читает и единственные значения и массивы от устройства, но всегда возвращает объект [] массив даже для одного значения. Это требует, чтобы повторенные вызовы возразили [0], когда я хотел бы, чтобы конечный пользователь смог использовать дженерики для получения или массива или единственного значения.
Я хочу использовать дженерики, таким образом, вызываемый может использовать обертку следующими способами:
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. Оцените T [], я получаю:
Не может преобразовать тип 'объект []' к 'T []'
Какие-либо идеи того, как достигнуть моей цели?Спасибо!
Изменить: обновлен ответ . Библиотека возвращает массив объектов, вы не сможете просто вернуть его как 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?
Вам нужно обмануть компилятор, сначала преобразовав массив в объект
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.
}
}