C # Свойство Ссылка - PullRequest
       1

C # Свойство Ссылка

3 голосов
/ 06 декабря 2011

С учетом следующего кода;

public class CustomControl {
    private object _dataItem;

    public object DataItem {
        get { return _dataItem; }
        set { _dataItem = value; }
    }

    public void Update(ref string t) {
        t = "test";
    }
}

public class Consume {
    public void Example() {
        CustomControl ctrl = new CustomControl();
        ctrl.DataItem = anyObject.anyProperty;

        string prop = anyObject.anyProperty;
        ctrl.Update(ref prop);
        anyObject.anyProperty = prop;
    }
}

Как я могу изменить его так, чтобы свойство DataItem само по себе являлось ссылкой, позволяя вам предварительно установить его так, чтобы оно указывало на переменную, позволяя вам вызывать Update() без каких-либо параметров.

Таким образом, класс Consume будет выглядеть примерно так:

public class Consume {
    public void Example() {
        CustomControl ctrl = new CustomControl();
        ctrl.DataItem = anyObject.anyProperty;
        ctrl.Update();

        // anyObject.anyProperty has been updated to "test"
    }
}

Таким образом, присвоение anyObject.anyProperty затем обрабатывается внутри CustomControl

Ответы [ 2 ]

5 голосов
/ 06 декабря 2011

Вам необходимо сохранить акт установки чего-либо в строку , поэтому сохраните Action<string>:

public class CustomControl {
    public Action<string> SetData { get; set; }

    public void Update() {
        // TODO nullity check
        SetData("test");
    }
}

Тогда Consume будет выглядеть так:

public class Consume {
    public void Example() {
        CustomControl ctrl = new CustomControl();

        // store {the act of setting this property of this object to a string}
        ctrl.SetData = s => anyObject.anyProperty = s;

        ctrl.Update();
    }
}

Вызов Update установит anyObject.anyProperty в test. Обратите внимание, что вы храните конкретный акт установки этого свойства конкретного anyObject, на который вы ссылаетесь в присваивании SetData.


Чтобы расширить лямбду: мы хотим создать значение типа Action<string>, то есть вещь , которая принимает string и не возвращает результата . Такой вещью будет исполняемый код . До C # 3, чтобы создать «значение», которое было исполняемым кодом, нам пришлось бы сделать что-то вроде:

    ctrl.SetData = delegate(string s) { someObject.SomeProperty = s; };

С этим синтаксисом становится более очевидным, что мы создаем метод - у него тело с разделителями { }, в нем есть операторы, и ясно, что есть строковый параметр, который используется тело.

Одна вещь, которая достигается с помощью лямбда-выражений в C # 3, - это возможность сжать это; слабо, всего

// not compilable code
delegate(parameters) { body; }

можно заменить на

// not compilable code
(parameters) => body;

и в случае, когда есть только один параметр

// not compilable code
parameter => body;

что и есть: выражение, присвоенное ctrl.SetData, представляет собой фрагмент поведения , которое принимает строку (s) и устанавливает anyObject.anyProperty для этой строки. Настоящая сила в том, что компилятор C # может определять типы, которые он знает, что мы создаем Action<string>.

1 голос
/ 06 декабря 2011

Сначала я не понял, что вы пытаетесь сделать. То, что вы ищете, это шаблон адаптера или фасада. То есть у вас есть объект с определенным интерфейсом, но вам нужно адаптировать его к другому интерфейсу или предоставить более простой интерфейс.

Одним из способов реализации этих шаблонов является использование композиции и делегирование нового интерфейса методам в существующем интерфейсе.

 public interface IUpdatable<U>
 {
      void Update( U newValue );
 }

 public abstract class CustomControl<T,U> : IUpdatable<U>
     where T : Control
 {
     private T  Control { get; set; }

     protected CustomControl( T control )
     {
          this.Control = control;
     }

     public abstract void Update( U newValue );
 }

 public class TextBoxFacade : CustomControl<TextBox,string>, IUpdatable<string>
 {
     public TextBoxFacade( TextBox textbox ) : base(textbox) { }

     public override void Update( string newValue )
     {
         this.Control.Value = newValue;
     }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...