如何创建对值字段的引用

发布于 2024-12-12 07:06:57 字数 414 浏览 0 评论 0原文

C# 中有没有办法创建一个字段,该字段是对另一个值类型字段的引用?

class myClass
{
    bool b1;

    public void method1(ref bool b)
    {
        b1 = b;
    }
}

我希望 b1 引用 b 的值,就像 b 引用原始参数的值一样,这样对 b1 的更改就会影响原始参数。

编辑:

我想要实现的是一个自动更新字段的 myCheckBox 类。请参阅:如何更改值来自事件处理程序内的参数?

Is there a way in C# to create a field which is a reference to another field which is a value type?

class myClass
{
    bool b1;

    public void method1(ref bool b)
    {
        b1 = b;
    }
}

I want b1 to reference the value of b, just as b references the value of the original argument, so that changes to b1 will affect the original argument.

EDIT:

What I’m trying to achieve is a myCheckBox class which automatically updates a field. See: How do I change a value argument from within an event handler?

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

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

发布评论

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

评论(4

凑诗 2024-12-19 07:06:57

当然!看看埃里克对此问题的回答:

在 C# 中设置成员字段的引用

正如其他人指出的那样,您无法存储对变量的引用
在 C# 或任何 CLR 语言的领域中。

当然,您可以捕获对类实例的引用
很容易包含一个变量

Sure! Take a look at Eric's answer to this question:

Setting a ref to a member field in C#

As others have pointed out, you cannot store a reference to a variable
in a field in C#, or indeed, any CLR language.

Of course you can capture a reference to a class instance that
contains a variable easily enough

寒冷纷飞旳雪 2024-12-19 07:06:57

嗯...当然有一种非常扭曲的方式:)。
那就是利用反射!
你无法获取字段的地址,但我们可以使用反射。

我警告你,反射比直接访问字段慢。
事实上,访问其他类的私有字段是一种非常糟糕的做法!
然而,当您无法控制其他人编写的代码时,有时对于一些肮脏的黑客攻击很有用。

这是例子,但我一直说,这不是一个好的做法,这里只是出于好奇和教育目的!

访问字段的另一种方法是使用属性或使用修改属性的类。

// Our FieldReference class that internally uses reflection to get or set a field value.
public class FieldReference<T>
{
    private object ownerObject;
    private FieldInfo fieldInfo;

    public FieldReference(object ownerObject, string fieldName)
    {
        this.ownerObject = ownerObject;
        this.fieldInfo = ownerObject.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    }

    public FieldReference(object ownerObject, FieldInfo fieldInfo)
    {
        this.ownerObject = ownerObject;
        this.fieldInfo = fieldInfo;
    }

    public T Value
    {
        get { return (T)this.fieldInfo.GetValue(this.ownerObject); }
        set { this.fieldInfo.SetValue(this.ownerObject, value); }
    }
}

// Our dummy class
public class MyClass
{
    // Our field we want to expose.
    private int myField;

    public MyClass(int value)
    {
        this.myField = value;
    }

    // Just a function we use to print the content of myField.
    public override string ToString()
    {
        return this.myField.ToString();
    }
}

class Program
{
    public static void Main()
    {
        // We create our class.
        MyClass mc = new MyClass(5);

        // We print field value, should be 5 :)
        Console.WriteLine(mc.ToString());

        // We create our field reference
        FieldReference<int> fieldref = new FieldReference<int>(mc, "myField");

        // We set the value using field reference.
        // Note, we accessed a private field :)
        fieldref.Value = 100;

        // Now we print the value, should be 100!
        Console.WriteLine(mc.ToString());

        Console.ReadLine();
    }
}

Well... there is a very contort way :) of course.
That is, using reflection!
You cannot get the address of a field, but we can use reflection.

Reflection is slower than accessing directly a field, i warn you.
And really, accessing private fields of other classes is a really bad practice!
Is however useful sometime for some dirty hacks when you don't have control of code written by other people.

Here the example, but i keep saying, it is not a good practice, is here only for curiosity and for educational purposes!

Fine another way to access your field, using properties or using a class that modify your properties.

// Our FieldReference class that internally uses reflection to get or set a field value.
public class FieldReference<T>
{
    private object ownerObject;
    private FieldInfo fieldInfo;

    public FieldReference(object ownerObject, string fieldName)
    {
        this.ownerObject = ownerObject;
        this.fieldInfo = ownerObject.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    }

    public FieldReference(object ownerObject, FieldInfo fieldInfo)
    {
        this.ownerObject = ownerObject;
        this.fieldInfo = fieldInfo;
    }

    public T Value
    {
        get { return (T)this.fieldInfo.GetValue(this.ownerObject); }
        set { this.fieldInfo.SetValue(this.ownerObject, value); }
    }
}

// Our dummy class
public class MyClass
{
    // Our field we want to expose.
    private int myField;

    public MyClass(int value)
    {
        this.myField = value;
    }

    // Just a function we use to print the content of myField.
    public override string ToString()
    {
        return this.myField.ToString();
    }
}

class Program
{
    public static void Main()
    {
        // We create our class.
        MyClass mc = new MyClass(5);

        // We print field value, should be 5 :)
        Console.WriteLine(mc.ToString());

        // We create our field reference
        FieldReference<int> fieldref = new FieldReference<int>(mc, "myField");

        // We set the value using field reference.
        // Note, we accessed a private field :)
        fieldref.Value = 100;

        // Now we print the value, should be 100!
        Console.WriteLine(mc.ToString());

        Console.ReadLine();
    }
}
屌丝范 2024-12-19 07:06:57

看起来使用委托/事件可以更好地解决问题。

不要尝试做不可能的事情(强制值类型表现为引用类型),而是使用事件并在该值发生更改时触发它。

从呼叫者那里订阅此活动,您就可以开始了。

Looks like something that is better solved using delegates/events.

Instead of trying to do the impossible (force value types to behave as reference types), use an event and fire it whenever this value is changed.

Subscribe to this event from the caller/s and you are good to go.

画中仙 2024-12-19 07:06:57

不知道您想要什么,可以为此使用委托,但它听起来确实像代码味道:

class myClass
{
    Action<bool> modify;

    public void method1(Action<bool> modify)
    {
        this.modify = modify;
    }

    public void ModifyIt()
    {
        modify(false);
    }
}


bool b1 = true; //b1 is true
var m = new myClass();
m.method1(val => { b1 = val; });
m.ModifyIt(); //b1 is false now

Not knowing what you would want this for you could use a delegate for this, it does sound like a code smell though:

class myClass
{
    Action<bool> modify;

    public void method1(Action<bool> modify)
    {
        this.modify = modify;
    }

    public void ModifyIt()
    {
        modify(false);
    }
}


bool b1 = true; //b1 is true
var m = new myClass();
m.method1(val => { b1 = val; });
m.ModifyIt(); //b1 is false now
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文