Почему явная интерфейсная реализация?

Если вы хотите вернуть «объединенный» канал до того, как он должен быть закрыт, нет.

Но это не проблема, запускаемая вами процедура будет использовать 0 ресурсов ЦП. Вам не стоит об этом беспокоиться.

Как только один из каналов будет закрыт, функция завершится, и, таким образом, процедура будет завершена должным образом. Вам нужно только убедиться, что хотя бы один из каналов закрыт. Если вы не можете гарантировать это, программа никогда не прекратит работу и никогда не будет собирать мусор. Если вы не контролируете каналы, вы можете пропустить 3-й канал (или значение context.Context), чтобы обеспечить способ правильного завершения, например:

func MergeChans(c1, c2, shutdown chan struct{}) chan struct{} {
    c3 := make(chan struct{})
    go func() {
        select {
        case <-c1:
            close(c3)
        case <-c2:
            close(c3)
        case <-shutdown:
        }
    }()
    return c3
}

Если вы хотите избежать дополнительной процедуры затем не объединяйте их (добавьте 2 case, где они должны контролироваться).

9
задан bmm6o 3 January 2009 в 01:46
поделиться

2 ответа

Это называют явной интерфейсной реализацией. В Вашем примере, так как Вы определяете Расположение () метод как "пустой IDisposable. Расположите ()", Вы явно реализуете интерфейс IDisposable также.

Это обычно делается для предотвращения коллизий. Если бы Microsoft когда-нибудь хотела добавить, что другой Располагает () метод, который сделал что-то еще к RegistryKey, то они не смогли бы к тому, если они не использовали явную реализацию того интерфейса.

Это часто делается с универсальным интерфейсом <T> IEnumerable. Это требует, чтобы Вы также реализовали неуниверсальный интерфейс IEnumerable. Единственным участником в этих двух интерфейсах является GetEnumerator, при этом универсальный - более полезен, таким образом, его обычно реализовываемый как это:

public clas SomeClass : IEnumerable<SomeOtherClass>
{
    public IEnumerator<SomeOtherClass> GetEnumerator ()
    {
        ...
    }

    IEnumerator IEnumerable.GetEnumerator ()
    {
        return GetEnumerator ();
    }
}

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

Посмотрите страницы 166-169 Программирования C# Jesse Liberty (у меня есть четвертый выпуск).

15
ответ дан 4 December 2019 в 15:27
поделиться

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

Это болезненно, если Вы имеете ссылку на объект и хотите назвать метод интерфейса (как вышеупомянутый пример), но я смягчаю его путем записи:

class C : IDisposable
{
    public IDisposable IDisposable { get { return this; } }
    void IDisposable.Dispose() { }
}

что означает, что вызов метода на C похож:

C c = ...
c.IDisposable.Dispose();

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

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

-2
ответ дан 4 December 2019 в 15:27
поделиться
Другие вопросы по тегам:

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