リフレクションを使用して、C#の読み取り専用の継承フィールドを変更できますか?
-
05-07-2019 - |
質問
Javaのように:
Class.getSuperClass().getDeclaredFields()
どのようにしてスーパークラスからプライベートフィールドを知り、設定できますか?
これは推奨されないことを強くお勧めしますが、アプリケーションをテストしているため、IDが正しく、名前が正しくないという間違った状況をシミュレートする必要があります。ただし、このIDはプライベートです。
解決
はい、リフレクションを使用して、コンストラクターの実行後に読み取り専用フィールドの値を設定できます
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);
ところで、パブリック/非パブリックフィールドまたはプロパティで動作します。使いやすくするために、次のような派生クラス PropertyValue を使用できます。
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);
すべてに感謝します。
所属していません StackOverflow