【问题标题】:How to create a reference to a value-field如何创建对值字段的引用
【发布时间】:2011-10-28 12:58:15
【问题描述】:

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

class myClass
{
    bool b1;

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

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

编辑:

我想要实现的是一个自动更新字段的 myCheckBox 类。见:How do I change a value argument from within an event handler?

【问题讨论】:

标签: c# reference


【解决方案1】:

当然!看看 Eric 对这个问题的回答:

Setting a ref to a member field in C#

正如其他人指出的那样,您不能存储对变量的引用 在 C# 或任何 CLR 语言的字段中。

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

【讨论】:

    【解决方案2】:

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

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

    这里是示例,但我一直在说,这不是一个好习惯,只是出于好奇和教育目的!

    使用属性或使用修改属性的类来访问您的字段的另一种方式。

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

    【讨论】:

      【解决方案3】:

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

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

      从调用者那里订阅此事件,您就可以开始了。

      【讨论】:

        【解决方案4】:

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

        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
        

        【讨论】:

          猜你喜欢
          • 2017-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-28
          相关资源
          最近更新 更多