C# вложенный родительский элемент доступа класса [дубликат]

Самый простой пример использования закрытий находится в чем-то названном приправлением карри. В основном давайте предположим, что у нас есть функция f(), который, когда названо с двумя аргументами a и b, добавляет их вместе. Так, в Python мы имеем:

def f(a, b):
    return a + b

, Но скажем, ради аргумента, который мы только хотим назвать f() с одним аргументом за один раз. Так, вместо f(2, 3), мы хотим f(2)(3). Это может быть сделано как так:

def f(a):
    def g(b): # Function-within-a-function
        return a + b # The value of a is present in the scope of g()
    return g # f() returns a one-argument function g()

Теперь, когда мы звоним f(2), мы получаем новую функцию, g(); эта новая функция несет с ним переменные от объем из [1 111], и таким образом, это сказано [1 120] близкий [более чем 1 120] те переменные, следовательно термин закрытие. К тому, когда мы звоним g(3), переменная a (который связывается определением f), получают доступ [1 115], возвращаясь 2 + 3 => 5

Это полезно в нескольких сценариях. Например, если бы у меня была функция, которая приняла большое количество аргументов, но только несколько из них были полезны для меня, я мог записать родовую функцию как так:

def many_arguments(a, b, c, d, e, f, g, h, i):
    return # SOMETHING

def curry(function, **curry_args):
    # call is a closure which closes over the environment of curry.
    def call(*call_args):
        # Call the function with both the curry args and the call args, returning
        # the result.
        return function(*call_args, **curry_args)
    # Return the closure.
    return call

useful_function = curry(many_arguments, a=1, b=2, c=3, d=4, e=5, f=6)

useful_function теперь функция, для которой только нужны 3 аргумента, вместо 9. Я избегаю необходимости повторять меня, и также создал универсальный решение; если я пишу другую функцию много-аргумента, я могу использовать curry инструмент снова.

35
задан Rob 9 July 2009 в 19:23
поделиться

6 ответов

Вы можете использовать что-то вроде этого:


class B {
    private MainClass instance;

    public B(MainClass instance)
    {
        this.instance = instance;
    }

    List SubSetList;

    public void AddNewItem(A NewItem) {
       Check MasterListHere ????
    }
  }
26
ответ дан 27 November 2019 в 07:05
поделиться

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

29
ответ дан 27 November 2019 в 07:05
поделиться

Согласно вашему определению, экземпляры класса B могут обращаться к закрытым методам и статическим полям класса MainClass .

5
ответ дан 27 November 2019 в 07:05
поделиться

Независимо от того, вкладываете ли вы класс B в класс A, любой данный экземпляр A все равно должен знать об экземпляре B, которым он удерживается. Таким образом, вы можете инициализировать A ссылкой на B и сохранить его в поле. Скорее всего, это включает его отключение.

1
ответ дан 27 November 2019 в 07:05
поделиться

Это может сработать для вас:

public void AddNewItem(A newItem, Func<A, bool> checkForItemInMasterList)
{
    if (checkForItemInMasterList.Invoke(newItem)
        SubList.Add(newItem);
}

Тогда у вас будет что-то в вашем MainClass, чтобы использовать такой метод:

public void AddItem(A newItem)
{
    new B().AddNewItem(newItem, x => MasterList.Contains(x));
}

To резюмируя, это может выглядеть примерно так:

class MainClass {
  class A { Whatever }

  class B {
    List<A> SubSetList;

    public void AddNewItem(A newItem, Func<A, bool> checkForItemInMasterList)
    {
        if (checkForItemInMasterList.Invoke(newItem)
            SubList.Add(newItem);
    }
  }

  //I don't know how you're adding items to instances of B.
  //This is purely speculative.
  public void AddItem(A newItem)
  {
      new B().AddNewItem(newItem, x => MasterList.Contains(x));
  }

  List<A> MasterList;
}
1
ответ дан 27 November 2019 в 07:05
поделиться

Да, но вам понадобится ссылка на экземпляр MainClass внутри вашего экземпляра B.

Вы думали о том, чтобы немного переделать свои классы? Вместо того, чтобы иметь метод AddNewItem в B, вы могли бы иметь его в MainClass. Таким образом было бы легко проверить MasterList из MainClass.

1
ответ дан 27 November 2019 в 07:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: