我可以使用反射更改 C# 中的私有只读继承字段吗?

发布于 2024-08-04 03:21:22 字数 181 浏览 4 评论 0原文

就像在java中一样,我有:

Class.getSuperClass().getDeclaredFields()

如何从超类中知道并设置私有字段?

我知道强烈不建议这样做,但我正在测试我的应用程序,我需要模拟 id 正确但名称不正确的错误情况。但这个ID是私有的。

like in java I have:

Class.getSuperClass().getDeclaredFields()

how I can know and set private field from a superclass?

I know this is strongly not recommended, but I am testing my application and I need simulate a wrong situation where the id is correct and the name not. But this Id is private.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你是我的挚爱i 2024-08-11 03:21:22

更新后,可以使用反射来设置只读字段的值

var fi = this.GetType()
             .BaseType
             .GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic);

fi.SetValue(this, 1);

是的,在构造函数运行EDIT

以查看直接父类型。如果类型是通用的,此解决方案可能会出现问题。

Yes, it is possible to use reflection to set the value of a readonly field after the constructor has run

var fi = this.GetType()
             .BaseType
             .GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic);

fi.SetValue(this, 1);

EDIT

Updated to look in the direct parent type. This solution will likely have issues if the types are generic.

情独悲 2024-08-11 03:21:22

是的,你可以。

对于字段,请使用 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"
}

Yes, you can.

For fields, use the FieldInfo class. The BindingFlags.NonPublic parameter allows you to see private fields.

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");
    }
}

and a small test to prove it works:

public static void Run()
{
    var derived = new Derived();
    Console.WriteLine(derived.Id); // prints "hi"
    derived.changeParentVariable();
    Console.WriteLine(derived.Id); // prints "sup"
}
黯然 2024-08-11 03:21:22

这个类可以让你做到这一点:

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;

This class will let you do it:

http://csharptest.net/browse/src/Library/Reflection/PropertyType.cs

Usage:

new PropertyType(this.GetType(), "_myParentField").SetValue(this, newValue);

BTW, It will work on public/non-public fields or properties. For ease of use you can use the derived class PropertyValue like this:

new PropertyValue<int>(this,  "_myParentField").Value = newValue;
顾北清歌寒 2024-08-11 03:21:22

正如 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);

感谢所有人。

Like JaredPar suggests, I did the follow:

//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);

Thanks to all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文