2014-01-23 3 views
0

В одном классе есть поле. Второй класс должен иметь возможность ссылаться на это поле и изменять его. Поскольку вы не можете получить адрес поля в памяти, я должен использовать отражения. Но мой подход работает только с неинкапсулированными полями. Так что в принципе:Полевые ссылки и размышления

Это работает:

public class Dummy 
{ 
    public int field; 
    public Dummy(int value) 
    { 
     this.field = value; 
    } 
} 

class Program 
{ 
    public static void Main() 
    { 
     Dummy d = new Dummy(20); 
     //Shows 20 
     Console.WriteLine(d.field.ToString()); 
     d.GetType().GetField("field", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(d, 40); 
     //It should show 40 now 
     Console.WriteLine(d.field.ToString()); 
    } 
} 

Это не (броски NullReferenceException):

public class Dummy 
{ 
    public int field { get; set; } 
    public Dummy(int value) 
    { 
     this.field = value; 
    } 
} 

class Program 
{ 
    public static void Main() 
    { 
     Dummy d = new Dummy(20); 
     //Shows 20 
     Console.WriteLine(d.field.ToString()); 
     d.GetType().GetField("field", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(d, 40); 
     //It should show 40 now 
     Console.WriteLine(d.field.ToString()); 
    } 
} 

Почему? Как это исправить? Могу ли я даже получить доступ к инкапсулированному объекту? Спасибо!

+2

В вашем втором примере это не 'поле', а свойство' property'. – EkoostikMartin

+2

Зачем вам нужно отражение здесь? И «поле», и «свойство» являются общедоступными, поэтому 'd.field = 40;' ... – Alden

+0

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

ответ

2

Это не поле. Вместо ПолучитьПолеЗаголовка вы должны использовать метод GetProperty:

d.GetType().GetProperty(...); 
+0

Это (конечно) работает! Большое спасибо! :) – JTaylor

2

В обоих случаях можно (и нужно) написать

d.field = 40; 

Если вы хотите поле, чтобы быть не частным, вы should always сделать это как и в вашем втором примере. У вас никогда не должно быть публичных полей. Обратите внимание: если вам нужно получить доступ к свойству через отражение, вы должны использовать GetProperty, а не GetField.

+0

Спасибо за ценную информацию. :) – JTaylor

0

Можете ли вы уточнить пример использования? Может быть интерфейс, который изолирует аксессор от свойств лучше:

public interface IDummy 
{ 
    int field { get; set; } 
} 

Вы будете в состоянии управлять имуществом, ничего не зная об остальной части объекта. Разве это не то, что вам нужно, когда вы хотите «ссылаться» на одно поле?

+0

Вы, безусловно, правы, но в моем случае слишком много возможностей для использования интерфейса. Мне просто нужен класс, который содержит ссылку на объект и когда он изменится - он изменяет поле/свойство в другом месте. Эта вещь есть просто глупый пример, чтобы понять, где ошибка. – JTaylor

+0

Отлично. Думаю, тогда вы будете опробовать значение. Излишне говорить, что сеттеры + события отлично подходят для этих случаев. Я чувствую, что у вас нет доступа к исходному коду и вы не можете обойти опрос ... – pid

Смежные вопросы