Различие между неявной и явной реализацией интерфейсов C# [дубликат]

Спасибо @JeremyBenks за идею использования взамен строки Base64. Соответствующие изменения для моего примера следующие:

JS

var binaryString = String.fromCharCode.apply(null, uintArray);

Для этого

var b64String = btoa(String.fromCharCode.apply(null,uintArray));

C #

byte[] bytes = Encoding.UTF8.GetBytes(model.FileContent);

Для этого [ 118]

byte[] bytes = Convert.FromBase64String(model.FileContent);
8
задан slugster 19 August 2015 в 00:04
поделиться

8 ответов

Другой аспект этого:

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

Если это явно реализовано, клиенты должны будут бросить Ваш класс к интерфейсу перед способностью получить доступ к участникам. Вот пример явной реализации:

    interface Animal
{
    void EatRoots();
    void EatLeaves();
}

interface Animal2
{
    void Sleep();
}


class Wombat : Animal, Animal2
{
    // Implicit implementation of Animal2
    public void Sleep()
    {
    }

    // Explicit implementation of Animal
    void Animal.EatRoots()
    {

    }

    void Animal.EatLeaves()
    {
    }

}

Ваш клиентский код

Wombat w = new Wombat();
w.Sleep();
w.EatRoots();   // This will cause a compiler error because it's explicitly implemented
((Animal)w).EatRoots();  // This will compile
13
ответ дан 5 December 2019 в 05:08
поделиться

IDE дает Вам опцию сделать любого - было бы необычно сделать обоих. С явной реализацией участники не находятся на (основном) общедоступном API; это удобно, если интерфейс непосредственно не связывается с намерением объекта. Например, ICustomTypeDescriptor участники не все это полезное постоянным вызывающим сторонам - только к некоторому очень определенному коду, таким образом, нет никакой цели, имеющей их на общедоступной путанице порождения API.

Это также полезно если:

  • между интерфейсом существует конфликт Foo метод и Ваш собственный тип Foo метод, и они имеют в виду разные вещи
  • между другими интерфейсами существует конфликт подписи

Типичный пример последней точки IEnumerable<T>, который имеет a GetEnumerator() метод на двух уровнях в интерфейсной иерархии - распространено реализовать введенный (IEnumerator<T>) версия с помощью неявной реализации и невведенного (IEnumerator) версия с помощью явной реализации.

10
ответ дан 5 December 2019 в 05:08
поделиться

Вот различие без обиняков:

Предположим, что у Вас есть интерфейс Machine, который имеет функцию Run(), и другой интерфейс Animal которому также назвали функцию Run(). Конечно, когда машина работает, мы говорим об этом запуск, но когда животное работает, мы говорим об этом перемещение. Таким образом, то, что происходит, когда у Вас есть объект, позволяет, называют его Aibo это оба a Machine и Animal? (Aibo является механической собакой, между прочим.), Когда Aibo выполнения, он запускает или действительно перемещается? Явно реализация интерфейса позволяет Вам сделать то различие:

interface Animal
{
    void Run();
}
interface Machine
{
    void Run();
}

class Aibo : Animal, Machine
{
    void Animal.Run()
    {
        System.Console.WriteLine("Aibo goes for a run.");
    }
    void Machine.Run()
    {
        System.Console.WriteLine("Aibo starting up.");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Aibo a = new Aibo();
        ((Machine)a).Run();
        ((Animal)a).Run();
    }
}

Выгода здесь - то, что я не могу просто звонить a.Run() потому что обе из моих реализаций функции явно присоединены к интерфейсу. Это имеет смысл, потому что иначе, как компилятор знал бы который звонить? Вместо этого если я хочу звонить Run() функция на моем Aibo непосредственно, я должен буду также реализовать ту функцию без явного интерфейса.

6
ответ дан 5 December 2019 в 05:08
поделиться

Явный поместит IInterfaceName. впереди всех интерфейсных реализаций. Полезно, если необходимо реализовать два интерфейса, которые содержат имена/подписи то столкновение.

Более подробная информация.

4
ответ дан 5 December 2019 в 05:08
поделиться

Здесь Вы идете, непосредственно из MSDN

0
ответ дан 5 December 2019 в 05:08
поделиться

Явно реализация ставит полностью определенное имя в имени функции, рассматривают этот код

    public interface IamSam
    {
        int foo();
        void bar();
    }

    public class SamExplicit : IamSam
    {
        #region IamSam Members

        int IamSam.foo()
        {
            return 0;
        }

        void IamSam.bar()
        {

        }

        string foo()
        {
            return "";
        }
        #endregion
    }

    public class Sam : IamSam
    {
        #region IamSam Members

        public int foo()
        {
            return 0;
        }

        public void bar()
        {

        }

        #endregion
    }

IamSam var1;
var1.foo()  returns an int.
SamExplicit var2;
var2.foo() returns a string.
(var2 as IamSam).foo() returns an int.
1
ответ дан 5 December 2019 в 05:08
поделиться

Различие - то, что можно наследовать класс от нескольких интерфейсов. Эти интерфейсы могут иметь идентичные Сигнатуры методов. Явная реализация позволяет Вам изменять свою реализацию, согласно которой Интерфейс использовался для вызова ее.

0
ответ дан 5 December 2019 в 05:08
поделиться

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

Например, если Ваш класс является Человеком, и интерфейс является ISerializable, не имеет большого смысла для кого-то имеющего дело с атрибутами Человека видеть, что что-то странное назвало 'GetObjectData' через Intellisense. Вы могли бы поэтому хотеть явно реализовать интерфейс.

С другой стороны, если Ваш класс человека, оказывается, реализует IAddress, имеет смысл видеть участников как AddressLine1, ZipCode и т.д. на экземплярах Человека непосредственно (неявная реализация).

0
ответ дан 5 December 2019 в 05:08
поделиться
Другие вопросы по тегам:

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