Используйте подмножество методов в качестве методов-членов в разных классах в C # - PullRequest
0 голосов
/ 19 октября 2019

Можно ли использовать подмножество методов в качестве методов-членов в различных классах в C #?

Например, у меня есть четыре функции void A(), void B(), void C() иvoid D().

А теперь я хочу провести три занятия. В первом классе я хотел бы иметь методы-члены A, B и C. Во-вторых, я хотел бы иметь B и D. И третий A, C и D.

Как я мог этого добиться? Можно ли добиться этого только с помощью интерфейсов или есть другие подходы?

Ответы [ 2 ]

0 голосов
/ 20 октября 2019
using System;

public interface MA {}
public static class MAProvider {
    public static void A(this MA obj) { Console.WriteLine("MA"); }
}

public interface MB {}
public static class MBProvider {
    public static void B(this MB obj) { Console.WriteLine("MB"); }
}

public interface MC {}
public static class MCProvider {
    public static void C(this MC obj) { Console.WriteLine("MC"); }
}

public interface MD {}
public static class MDProvider {
    public static void D(this MD obj) { Console.WriteLine("MD"); }
}

public class First : MA, MB, MC {}
public class Second : MB, MD {}
public class Third : MA, MC, MD {}

public static class Program {
    public static void Main() {
        new First().A();
        new First().B();
        new First().C();

        new Second().B();
        new Second().D();

        new Third().A();
        new Third().C();
        new Third().D();
    }
}

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

0 голосов
/ 19 октября 2019

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

public interface IHaveA {
    void A();
}

public interface IHaveB {
    void B();
}

public interface IHaveC {
    void C();
}

public interface IHaveD {
    void D();
}

public class Class1 : IHaveA, IHaveB, IHaveC { // Implement A, B and C here }

public class Class2 : IHaveB, IHaveD { // Implement B and D here  }

public class Class3 : IHaveA, IHaveC, IHaveD { // Implement A, C and D here  }

Если все ваши классы должны иметь та же реализация A, B, C и D, вы все равно можете использовать интерфейсы, но вам придется дублировать код:

public static class StaticImplementation {
    public void A(IHaveA sender) {
        // Do stuff here
    }

    public void B(IHaveB sender) {
        // Do stuff here
    }
    public void C(IHaveC sender) {
        // Do stuff here
    }

    public void D(IHaveD sender) {
        // Do stuff here
    }
}

public class Class1 : IHaveA, IHaveB, IHaveC {
    public void A() { StaticImplementation.A(this) }
    public void B() { StaticImplementation.B(this) }
    public void C() { StaticImplementation.C(this) }
}

public class Class2 : IHaveB, IHaveD { // Calls to StaticImplementation for B and D here  }

public class Class3 : IHaveA, IHaveC, IHaveD { // Calls to StaticImplementation for A, C and D here  }

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

Это изменяется в C # 8.0 и .NET Core3.0 , где у вас могут быть реализации по умолчанию для методов интерфейса, и вы можете гарантировать, что эти реализации не изменятся, запечатав их.

Код станет:

public interface IHaveA {
    sealed void A() {
        // Implementation here
    }
}

public interface IHaveB {
    sealed void B() {
        // Implementation here
    }
}

public interface IHaveC {
    sealed void C() {
        // Implementation here
    }
}

public interface IHaveD {
    sealed void D() {
        // Implementation here
    }
}

public class Class1 : IHaveA, IHaveB, IHaveC { // Nothing to do here }

public class Class2 : IHaveB, IHaveD { // Nothing to do here  }

public class Class3 : IHaveA, IHaveC, IHaveD { // Nothing to do here  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...