2015-03-19 5 views
1

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

Например:

class Thing 
{ 
    protected int i; 
    public virtual int I 
    { 
     get 
     { 
      return i; 
     } 
    } 
} 
class OtherThing 
{ 
    public virtual void ChangeI(Thing thing, int i) 
    { 
     thing.i = i; 
    } 
} 

Здесь я хочу OtherThing, чтобы иметь возможность получить доступ к я, или защищенный набор метод I в Вещь, несмотря на то, что он определен за пределами Вещь.

Я признаю, что я мог бы просто объявить OtherThing внутри рамки Thing, который затем иметь разрешение на доступ к защищенным пунктов, однако я также хотел бы, чтобы это работать с интерфейсами, чьи реализации не может быть определены в рамках исходного интерфейса и не могут объявлять защищенные методы в любом случае.

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

Заранее спасибо.

+0

Конечно, это не отвечает на вопрос, но сначала подумал, что мне приходит в голову - почему вы хотите нарушить инкапсуляцию «Вещей»? –

+0

Это 'virtual int I {get; } 'указывает, что подкласс может реализовать свойство без использования поля' i'. Тогда OtherThing может установить его на что угодно, это не повлияет на значение свойства. – wigy

+0

Гипотетический, который я изложил, просто в качестве руководства. Я ищу конкретный тип поведения, и если он не существует, я попытаюсь его обойти. Ради простоты и потому, что это вообще не так, давайте предположим, почему «почему» не имеет значения. – user2312610

ответ

2

Когда я прочитал этот вопрос он чувствует себя довольно много, как шаблон для посетителей: http://www.dofactory.com/net/visitor-design-pattern

Давайте предположим, что у вас есть посетитель:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var thing = new Thing(); 
      var otherThing = new OtherThing(); 
      thing.Accept(otherThing); 
      Console.WriteLine(thing.I); 
      Console.Read(); 
     } 
    } 

    class OtherThing 
    { 
     public void Change(Action<int> setI) 
     { 
      setI(42); 
     } 
    } 

    class Thing 
    { 
     private int i; 

     public int I { get { return i; } } 

     public void Accept(OtherThing visitor) 
     { 
      visitor.Change(SetI); 
     } 

     private void SetI(int i) 
     { 
      this.i = i; 
     } 
    } 

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

Я действительно не понимаю причину, поэтому мой пример очень искусственный. В любом случае вы можете добавлять интерфейсы для абстрагирования вещей, даже использовать какую-то команду для передачи вместо Action. Но идея останется прежней.

+0

Мне нравится идея использования делегата, чтобы выставлять сеттер вместо интерфейса. – wigy

+0

Это выглядит как фантастический способ справиться с этой проблемой, спасибо большое! Спасибо за попытку работать с гипотетическим - как сейчас; Я могу взять общий ответ, который вы мне дали, и работать с ним и понимать его. Я думаю, что это намного лучший результат, чем преодоление множества альтернатив. – user2312610

2

Возможно, вы ищете концепцию класса из C++ в C#. C# не имеет такой функции на уровне класса, поэтому вам нужно найти другую альтернативу дизайна.

+0

Я никогда не слышал о ключевом слове 'friend' в C++ до сих пор - спасибо. Жаль, что в C# нет аналога. – user2312610

Смежные вопросы