Как сделать поле настраиваемым только внутри метода расширения - PullRequest
0 голосов
/ 09 марта 2019

Здравствуйте, я хочу иметь возможность установить a поля объекта только в методе extension. Я хотел бы, чтобы это поле было либо полностью закрытым, либо могло быть просто get доступным извне:

public class Myclass
{
   private int Value{get;set;}
}
public static class Ext
{
   public Myclass SetValue(this Myclass obj,int val)
   {
       this.obj.Value=val;
       return obj;
   }
}

Как вы можете видеть в приведенном выше примере, я должен объявить Value public, чтобы иметь возможность доступа к нему внутри расширения, я был бы согласен с этим, если бы я мог сделать переменную только get-able извне.

Мне нужна эта функциональность, потому что я хочу разработать что-то вроде fluent API, где вы можете установить только некоторые переменные, используя расширение.

например:

      a=new Myclass();
      a.SetValue1(1).SetValue2(2);//--some code //--a.SetValue3(3);

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

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

Требуемое поведение ограничено методами или свойствами экземпляра. Моя рекомендация - добавить метод экземпляра в класс.

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

public static class Ext
{
    public Myclass SetValue(this Myclass obj,int val)
    {
        var myType = typeof(Myclass);

        var myField = myType.GetField("Value", BindingFlags.NonPublic | BindingFlags.Instance);

        myField.SetValue(obj, val);

        return obj;
   }
}

Обратите внимание, что здесь есть следующие ошибки:

  1. Нет проверок времени компиляции, чтобы спасти вас, если вы решите переименовать поле Value. (хотя юнит-тесты могут защитить вас)
  2. Отражение обычно намного медленнее, чем обычные методы экземпляра. (хотя производительность может не иметь значения, если этот метод не вызывается часто)
1 голос
/ 09 марта 2019

вы хотите, чтобы это делалось с помощью метода расширения, но вы не можете в этом случае.

Ваш лучший вариант -

public class Myclass
{
   public int Value{get; private set;}

   public Myclass SetValue(int val)
   {
       this.Value=val;

       return obj;
   }
}
...