Используйте отражение, чтобы установить значение поля в структуре, которая является частью массива структур - PullRequest
3 голосов
/ 21 марта 2009

В данный момент мой код успешно устанавливает значение полей / свойств / массивов объекта, используя отражение с указанием пути к полю / свойству от корневого объекта.

, например

//MyObject.MySubProperty.MyProperty
SetValue('MySubProperty/MyProperty', 'new value', MyObject);

В приведенном выше примере свойство MyProperty объекта «MyObject» будет установлено в «новое значение»

Я не могу использовать отражение, чтобы установить значение поля в структуре, которая является частью массива структур, потому что структура является типом значения (внутри массива).

Вот некоторые тестовые классы / структуры ...

public class MyClass {
        public MyStruct[] myStructArray = new MyStruct[] {
            new MyStruct() { myField = "change my value" } 
        };
        public MyStruct[] myOtherStructArray = new MyStruct[] {
            new MyStruct() { myOtherField = "change my value" }, 
            new MyStruct() { myOtherField = "change my other value" } 
        };
}

public struct MyStruct { public string myField; public string myOtherField; }

Ниже показано, как я успешно установил значение обычных свойств / полей и реквизитов / полей в списках ...

public void SetValue(string pathToData, object newValue, object rootObject)
{
    object foundObject = rootObject;
    foreach (string element in pathToData.Split("/"))
    {
        foundObject = //If element is [Blah] then get the
                      //object at the specified list position
        //OR
        foundObject = //Else get the field/property
    }

    //Once found, set the value (this is the bit that doesn't work for
    //                           fields/properties in structs in arrays)
    FieldInf.SetValue(foundObject, newValue);
}

object myObject = new MyClass();
SetValue("/myStructArray/[0]/myField", "my new value", myObject);
SetValue("/myOtherStructArray/[1]/myOtherField", "my new value", myObject);

После этого я хочу myObject.myStructArray [0] .myField = '' мое новое значение "и myObject.myOtherStructArray [1] .myOtherField = '' мое новое значение "

Все, что мне нужно, это замена 'FieldInf.SetValue (foundObject, newValue);' линия

заранее спасибо

Ответы [ 4 ]

3 голосов
/ 21 марта 2009

Получить FieldInfo для объекта массива (не конкретного элемента).

Если это массив, приведите его к System.Array и используйте Array.SetValue для установки значения объекта.

2 голосов
/ 17 июня 2011

Из-за коробок / распаковок следующее должно делать именно то, что вы ищете, для любого вида члена структуры:

var property = this.GetType().GetProperty(myPropertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
ValueType vthis = this;
property.SetValue(vthis, myValue, null); // myValue is the value/object to be assigned to the property.
this = (UnderlyingsList)vthis;
1 голос
/ 21 марта 2009

Если бы мне пришлось угадывать, ошибка в той части кода, которую вы пропустили, в частности, я подозреваю, что:

    foundObject = //If element is [Blah] then get the
                  //object at the specified list position

(непреднамеренно) устанавливает foundObject в копию объекта в указанной позиции списка.

0 голосов
/ 21 марта 2009

Мой вопрос продолжается ...

Единственное решение, которое я нашел для аналогичной проблемы, которое я имел, устанавливая поле / свойство в структуре, которая является полем, было использовать ...

//GrandParentObject is myObject
//GrandParentType is typeof(MyClass)
//FieldIWantedToSet is the field info of myStruct.FieldIWantedToSet
FieldInfo oFieldValueTypeInfo = GrandParentType.GetField("myStruct");
TypedReference typedRefToValueType = TypedReference.MakeTypedReference(GrandParentObject, new FieldInfo[] { oFieldValueTypeInfo });
FieldIWantedToSet.SetValueDirect(typedRefToValueType, "my new value"); 

Проблема в том, как я могу использовать SetValueDirect для массива / списка структур, я предполагаю, что мой старый метод выше не будет работать, когда структуры находятся в массиве, потому что я не могу получить FieldInfo для структуры (потому что он в массив)?

...