[英]C# generics when T could be an array
I am writing a C# wrapper for a 3rd party library that reads both single values and arrays from a hardware device, but always returns an object[] array even for one value. 我正在为第三方库编写一个C#包装器,它从硬件设备读取单个值和数组,但总是返回一个object []数组,即使是一个值也是如此。 This requires repeated calls to object[0] when I'd like the end user to be able to use generics to receive either an array or single value. 当我希望最终用户能够使用泛型来接收数组或单个值时,这需要重复调用object [0]。
I want to use generics so the callee can use the wrapper in the following ways: 我想使用泛型,以便被调用者可以通过以下方式使用包装器:
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[];
In MyWrapper I have the Value property currently as the following: 在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.
}
}
I get a compile error in the first case: 我在第一种情况下遇到编译错误:
Cannot convert type 'object[]' to 'T' 无法将'object []'类型转换为'T'
If I change MyWrapper.Value to T[] I receive: 如果我将MyWrapper.Value更改为T [],我会收到:
Cannot convert type 'object[]' to 'T[]' 无法将'object []'类型转换为'T []'
Any ideas of how to achieve my goal? 有关如何实现目标的任何想法? Thanks! 谢谢!
Edit: Updated answer . 编辑:更新的答案 。 The library is returning an object array, you will not be able to simply return it as T, be it an array or a single element, without doing some work with it. 该库正在返回一个对象数组,您将无法简单地将其作为T返回,无论是数组还是单个元素,而无需使用它。 The function below is an example of taking an array of objects and either returning it as an array or a single element. 下面的函数是获取对象数组并将其作为数组或单个元素返回的示例。
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
}
}
Example of consuming it: 消费它的例子:
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?
You need to trick the compiler by casting your array into an object first 您需要先通过将数组转换为对象来欺骗编译器
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.
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.