2010-01-07 2 views
3

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

struct headerIndexes 
    { 
     public int AccountNum{ get; set; } 
     public int other { get; set; } 
     public int items { get; set; } 
    } 
    static void Main(string[] args) 
    { 

     headerIndexes headers = new headerIndexes(); 
     headers.AccountNum = 1; 
     Console.WriteLine("Old val: {0}", headers.AccountNum); 
     foreach (var s in headers.GetType().GetProperties()) 
     { 
      if (s.Name == "AccountNum") 
       s.SetValue(headers, 99, null); 
     } 
     Console.WriteLine("New val: {0}", headers.AccountNum); 
     Console.ReadKey(); 
    } 

Steping Копание программы я вижу, он правильно делает команду s.SetValue(headers, 99, null); однако значение headers.AccountNum остается на 1, когда SetValue запускается.

Я пропустил очевидный шаг?

+0

Несвязанные структуры являются злыми. http://blogs.msdn.com/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx –

ответ

3

Я думаю, что заголовки могут быть помещены в новый объект, поскольку это структура, тогда объект получает сбор мусора, как только SetValue возвращается. Измените его на класс и посмотрите, не исчезла ли проблема.

+0

Так оно и было, изменив его из структуры в класс, решила проблему. –

1

SetValue ожидает object, который вызывает боксерскую операцию на headers. Поскольку headers является struct, это тип значения. Поэтому копия сделана и то, что вы изменяете, это объект в штучной упаковке, а не headers.

Вам следует серьезно подумать об избежании изменчивых типов значений.

От Eric Lippert:

Это еще одна причина, почему изменяемые типы значений зла. Старайтесь всегда делать типы значений неизменяемыми.

1

Также вы можете использовать unboxed версию struct.
объект unboxedHeader = заголовки;
s.SetValue (unboxedHeader, 99, null);

struct headerIndexes 
{ 
    public int AccountNum{ get; set; } 
    public int other { get; set; } 
    public int items { get; set; } 
} 
static void Main(string[] args) 
{ 

    headerIndexes headers = new headerIndexes(); 
    headers.AccountNum = 1; 
    Console.WriteLine("Old val: {0}", headers.AccountNum); 
    object unboxedHeader=headers; 
    foreach (var s in headers.GetType().GetProperties()) 
    { 
     if (s.Name == "AccountNum") 
      s.SetValue(unboxedHeader, 99, null); 
    } 
    Console.WriteLine("New val: {0}", headers.AccountNum); 
    Console.ReadKey(); 
}