Как моделировать множественное наследование в C#

Как может я делать это:

Class A : DependencyObject {}

Class B : DependencyObject {}

Class C : A , B {}
9
задан John Saunders 8 July 2010 в 03:14
поделиться

8 ответов

В C# нет множественного наследования, поэтому строка

Class C : A , B {}

никогда не будет работать. Однако вы можете делать подобные вещи с интерфейсами, например, так:

interface InterfaceA { void doA(); } 
class A : InterfaceA { public void doA() {} }

interface InterfaceB { void doB(); }
class B : InterfaceB { public void doB() {}}

class C : InterfaceA, InterfaceB
{
  m_A = new A();
  m_B = new B();

  public void doA() { m_A.doA(); }
  public void doB() { m_B.doB(); } 
}
31
ответ дан 4 December 2019 в 06:05
поделиться

В C # нельзя выполнять множественное наследование, но можно реализовать несколько интерфейсов:

  1. Создайте интерфейс с теми же методами, что и открытые члены A
  2. Создайте интерфейс с те же методы, что и открытые члены B
  3. Создайте переменные-члены для A и B внутри C.
  4. Реализуйте интерфейс A как из A, так и из C (реализация C просто вызывает свою переменную-член типа A)
  5. Реализовать интерфейс B как из B, так и из C (реализация C просто вызывает свою переменную-член типа B)
7
ответ дан 4 December 2019 в 06:05
поделиться

К лучшему или худшему, C# не поддерживает множественное наследование. Однако я добился ограниченного успеха в его имитации с помощью методов расширения. Подход с использованием методов расширения может выглядеть следующим образом.

public class A
{
  public void DoSomething() { }
}

public static class B
{
  public static void DoSomethingElse(this A target) { }
}

public class C : A
{
}

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

С другой стороны, C# поддерживает реализацию нескольких интерфейсов. Это будет выглядеть следующим образом.

public interface IA
{
  void DoSomething();
}

public interface IB
{
  void DoSomethingElse();
}

public class A : IA
{
  void DoSomething() { }
}

public class B : IB
{
  void DoSomethingElse() { }
}

public class C : IA, IB
{
  private A m_A = new A();
  private B m_B = new B();

  public void DoSomething() { m_A.DoSomething(); }

  public void DoSomethingElse() { m_B.DoSomethingElse(); }
}

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

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

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

Другой способ, который не использует композицию, использует методы расширения. Определите интерфейсы, не имеющие методов, и реализуйте их в своем классе C. Затем напишите статический класс с методами расширения, которые обеспечивают реализацию вашего интерфейса.

public static void MyMethod(this InterfaceA a)
{
    // do stuff with a
}

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

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

Нельзя, чтобы C был одновременно A и B, если только один из них не наследуется от другого.

Однако, если вы хотите, чтобы C имел поведение от A и B, которое не является общим для них обоих, используйте интерфейс.

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

Вы можете достичь этого с помощью многоуровневого наследования...

 public class DependencyObject
{
    public void DependencyObjectMethod() { }
}

public class A : DependencyObject
{
    public void MethodA() { }
}

public class B : A
{
    public void MethodB() { }
}

public class C : B
{
    public void MethodC()
    {
        //Do Something
    }
}

С помощью этого вы можете получить доступ ко всем методам и свойствам этих классов.

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

Вы не можете, C# не поддерживает множественное наследование классов.

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

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

Так что я думаю, это не может быть сделано так ...

class A : DependencyObject
    {
        public int X
        {
            get { return (int)GetValue(XProperty); }
            set { SetValue(XProperty, value); }
        }
        public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(int), typeof(A), new UIPropertyMetadata(0));
    }

    class B : DependencyObject
    {
        public int X
        {
            get { return (int)GetValue(XProperty); }
            set { SetValue(XProperty, value); }
        }
        public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(int), typeof(B), new UIPropertyMetadata(0));
    }

    class C : DependencyObject
    {
        A a = new A();
        B b = new B();
        public int X
        {
            get { return a.X; }
            set { a.X = value; }
        }
        public int Y
        {
            get { return b.X; }
            set { b.X = value; }
        }
    }
0
ответ дан 4 December 2019 в 06:05
поделиться
Другие вопросы по тегам:

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