Как создать ссылку на поле значения - PullRequest
2 голосов
/ 28 октября 2011

Есть ли способ в C # создать поле, которое является ссылкой на другое поле, которое является типом значения?

class myClass
{
    bool b1;

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

Я хочу, чтобы b1 ссылался на значение b, так же как b ссылается назначение исходного аргумента, чтобы изменения в b1 повлияли на исходный аргумент.

EDIT:

Я пытаюсь достичь класса myCheckBox, который автоматически обновляет поле.См .: Как изменить аргумент значения из обработчика события?

Ответы [ 4 ]

3 голосов
/ 28 октября 2011

Конечно! Посмотрите на ответ Эрика на этот вопрос:

Установка ссылки на поле члена в C #

Как уже отмечали другие, вы не можете хранить ссылку на переменную в поле в C #, или, действительно, любой язык CLR.

Конечно, вы можете захватить ссылку на экземпляр класса, который содержит переменную достаточно легко

2 голосов
/ 28 октября 2011

Ну ... есть очень странный путь :) конечно. То есть используя отражение! Вы не можете получить адрес поля, но мы можем использовать отражение.

Отражение медленнее, чем прямой доступ к полю, предупреждаю вас. И действительно, доступ к закрытым полям других классов - очень плохая практика! Однако иногда полезно для некоторых грязных хаков, когда у вас нет контроля над кодом, написанным другими людьми.

Вот пример, но я продолжаю говорить, что это не очень хорошая практика, здесь только для любопытства и в образовательных целях!

Прекрасный другой способ получить доступ к вашему полю, используя свойства или класс, который изменяет ваши свойства.

// 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();
    }
}
2 голосов
/ 28 октября 2011

Похоже, что-то, что лучше решается с помощью делегатов / событий.

Вместо того, чтобы пытаться сделать невозможное (заставить типы значений вести себя как ссылочные типы), используйте событие и запускайте его всякий раз, когда это значение изменяется.

Подпишитесь на это событие от абонентов, и вы готовы идти.

1 голос
/ 28 октября 2011

Не зная, что вы хотите, чтобы это для вас может использовать делегата для этого, хотя звучит как запах кода:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...