简体   繁体   English

在不知道数组类型的情况下设置数组值

[英]Setting array values without knowing its type

I have an array of MyType s in an object similar to the setup below, I want to be able to set the value of an index on myObject as it is, I cannot change the declaration of MyFunction. 我在与下面的设置类似的对象中有一个MyType数组,我希望能够按原样设置myObject上的索引值,我无法更改MyFunction的声明。

/*...*/
MyType [] myTypedArray = new MyType[100];
MyFunction(myTypedArray);
/*...*/

function MyFunction(object myObject)
{
    myObject[0] = new MyType();
}

This, obviously, doesn't work but I cannot figure out how to get it to work. 显然,这不起作用,但是我无法弄清楚如何使其起作用。 I cannot cannot use templates/generics it has to be all using reflection. 我不能使用模板/泛型,必须全部使用反射。

Note that I have to have myObjectArray, initially, as an "object" as this is how I receive it. 请注意,最初我必须将myObjectArray作为“对象”,因为这是我收到它的方式。 I cannot do the initial cast to a object[]. 我无法对对象[]进行初始转换。 I have tried casting myObjectArray to object[] and it doesn't work. 我尝试将myObjectArray强制转换为object [],但它不起作用。

I also do not have access to MyType as a static type, only runtime. 我也没有访问MyType的静态类型,只有运行时。

Any advice would be great, thanks. 任何建议都很好,谢谢。

Declare myObjectArray as an array of object s: myObjectArray声明为object s的数组:

object[] myObjectArray = myTypedArray;
myObjectArray[0] = new MyType(); // okay to go!

Alternatively, if for some reason myObjectArray must be an object you can say: 或者,如果由于某种原因myObjectArray必须是一个object ,则可以说:

((object[])myObjectArray)[0] = new MyType();

These are smelly though. 这些虽然臭。 And beware of array covariance in C# ! 并注意C#中数组协方差

Here's an implementation along the lines that you seem to be looking for: 这是您似乎在寻找的一种实现方式:

void AddToArray(object array, int index) {
    if(array == null) {
        throw new ArgumentNullException();
    }
    Type arrayType = array.GetType();
    if(!arrayType.IsArray) {
        throw new InvalidOperationException("array must be an Array");
    }

    (Array)asArray = (Array)array;
    if (index < 0 || index >= asArray.Length) {
        throw new ArgumentOutOfRangeException("index");
    }
    object newInstance = Activator.CreateInstance(elementType);
    asArray.SetValue(newInstance, index);
}

Invoke as: 调用为:

AddToArray(myObjectArray, 0);

This assumes that elementType has a parameterless constructor. 假定elementType具有无参数构造函数。 There are ways around this, but this should be enough to get you started. 有很多解决方法,但这足以让您入门。 This method also probably needs a better name. 此方法可能还需要一个更好的名称。

Again, this code is very smelly. 同样,此代码很臭。 I would suggest taking a step back and seeing if you can solve your problem using strongly-typed code. 我建议退后一步,看看是否可以使用强类型代码解决问题。

Try something like: 尝试类似:

DayOfWeek[] myTypedArray = Enum.GetValues(typeof(DayOfWeek))
                               .OfType<DayOfWeek>().ToArray();
object myObject = myTypedArray;

object[] myObjectArray =   // from object to object[]
        (myObject as Array ?? new object[0]).OfType<object>().ToArray();

Type type = myObjectArray[0].GetType(); // unbox type
myObjectArray[0] = Activator.CreateInstance(type); // create another instance

Note you'll lose type safety. 请注意,您将失去类型安全性。

You can cast the object to an Array and call SetValue on it, for a completely non-object-specific way of doing it. 您可以将对象强制转换为Array并对其调用SetValue ,以实现完全非对象特定的方式。 This'll box & unbox value types as appropriate & do all the necessary array type checking. 这将适当地装箱和拆箱值类型,并进行所有必要的数组类型检查。

在这种情况下,您需要强制转换为object[]

((object[])myObjectArray)[0] = new MyType();

((MyType[])myObjectArray)[0] = new MyType(); perhaps? 也许?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM