Могу ли я изменить частное унаследованное поле только для чтения в C# с помощью отражения?
-
05-07-2019 - |
Вопрос
как в Java, у меня есть:
Class.getSuperClass().getDeclaredFields()
как я могу узнать и установить частное поле из суперкласса?
Я знаю, что это настоятельно не рекомендуется, но я тестирую свое приложение, и мне нужно смоделировать неправильную ситуацию, когда идентификатор правильный, а имя нет.Но этот идентификатор является частным.
Решение
Да, можно использовать отражение для установки значения поля только для чтения после запуска конструктора.
var fi = this.GetType()
.BaseType
.GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);
РЕДАКТИРОВАТЬ
Обновлено для просмотра в прямом родительском типе.Это решение, вероятно, будет иметь проблемы, если типы являются универсальными.
Другие советы
Да, вы можете.
Для полей используйте класс FieldInfo
. Параметр BindingFlags.NonPublic
позволяет просматривать личные поля.
public class Base
{
private string _id = "hi";
public string Id { get { return _id; } }
}
public class Derived : Base
{
public void changeParentVariable()
{
FieldInfo fld = typeof(Base).GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic);
fld.SetValue(this, "sup");
}
}
и небольшой тест, чтобы доказать, что это работает:
public static void Run()
{
var derived = new Derived();
Console.WriteLine(derived.Id); // prints "hi"
derived.changeParentVariable();
Console.WriteLine(derived.Id); // prints "sup"
}
Этот класс позволит вам сделать это:
http://csharptest.net/browse/src/Library/Reflection/PropertyType.cs
Использование:
new PropertyType(this.GetType(), "_myParentField").SetValue(this, newValue);
Кстати, он будет работать с общедоступными/закрытыми полями или свойствами.Для простоты использования вы можете использовать производный класс Стоимость имущества так:
new PropertyValue<int>(this, "_myParentField").Value = newValue;
Как предлагает JaredPar, я сделал следующее:
//to discover the object type
Type groupType = _group.GetType();
//to discover the parent object type
Type bType = groupType.BaseType;
//now I get all field to make sure that I can retrieve the field.
FieldInfo[] idFromBaseType = bType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
//And finally I set the values. (for me, the ID is the first element)
idFromBaseType[0].SetValue(_group, 1);
Спасибо всем.