Попытка наследовать три базовых класса и не может

22

У меня есть несколько вопросов, связанных с дизайном моего класса User , но они достаточно разные, что я думаю, что они должны быть независимыми вопросы.

Итак, первое связано с наследованием базовых классов. Я сейчас наследуя два класса, ProfileBase и ISessionMgrEntry как таковые:

public class User : ProfileBase, ISessionMgrEntry

Но я также хочу наследовать третий класс, MembershipUser , например:

public class User : ProfileBase, MembershipUser, ISessionMgrEntry

Однако компилятор не позволит мне сделать это. Зачем? И как я могу получить вокруг этого?

Спасибо.

PS - ASP.NET 3.5 / C #

ИЗМЕНИТЬ

Привет. Я думаю, что приведенное ниже решение может работать для того, что я пытаюсь достичь. Это кажется довольно простым и понятным. Я делаю это, чтобы я мог создать полный / комбинированный объект User . Кто-нибудь видит какую-либо причину, почему это может вызвать проблемы? Тот, который появился, когда я звонил, это перекрывающиеся свойства. Например, MembershipUser и ProfileBase разделяют « UserName ». Должен ли я просто выбрать один или другой, или это будет недостаток дизайна? Предложения? Еще раз спасибо.

 public class User
    {

        #region Constructors
            private readonly MembershipUser _MembershipUser;
            private readonly ProfileBase _ProfileBase;
        #endregion

        public User()
        {
            _MembershipUser = new MembershipUser();
            _ProfileBase = new ProfileBase();

        }

        public string Comment
        {
            get { return _MembershipUser.Comment as string; }
            set { _MembershipUser.Comment = value; }
        }

        public bool IsAnonymous
        {
            get { return _ProfileBase.IsAnonymous as bool; }
        } 

        ....

   }
    
задан Peter 04.02.2010 в 16:56
источник
  • Почему вы делаете это как на реквизитах? –  ChaosPandion 05.02.2010 в 19:12
  • Вы правы, я подумал, что оторвался. Я придерживался этого соглашения, но понимаю, что это другой случай: [SettingsAllowAnonymous (false), CustomProviderData («IPAddress; string»)] public string IPAddress {get {return base ["IPAddress"] как строка; } set {base ["IPAddress"] = значение; }} –  Peter 05.02.2010 в 20:05

7 ответов

36

В первом примере вы на самом деле наследуете не от двух классов, а от одного класса и интерфейса.

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

Вам нужно будет создать интерфейс IMembershipUser и реализовать его в своем классе User .

Интерфейсам обычно дают имена на основе конкретного имени класса с префиксом I . Таким образом, класс MembershipUser будет иметь интерфейс IMembershipUser . Ничто не мешает вам использовать какое-то другое имя, но каждый, кто использует интерфейсы, привык к этому соглашению об именах.

    
ответ дан ChrisF 04.02.2010 в 16:58
  • Спасибо Крису. Не могли бы вы взглянуть на мою Редактировать, когда у вас есть момент? В очередной раз благодарим за помощь. –  Peter 05.02.2010 в 19:00
  • @Code Sherpa - мне действительно нужно будет видеть больше вашего кода и иметь больше разговоров, чем это возможно через SO, но если у вас есть дублированные свойства, вы должны смотреть на другую иерархию классов. –  ChrisF♦ 05.02.2010 в 19:14
6

в c # вы можете наследовать от одного класса , но реализовывать столько интерфейсов , сколько захотите. в вашем случае ProfileBase и MembershipUser являются классами, а ISessionMgrEntry является интерфейсом.

    
ответ дан nWorx 04.02.2010 в 16:59
3

C # не допускает множественное наследование .     

ответ дан BlueRaja - Danny Pflughoeft 04.02.2010 в 16:59
3

C # поддерживает только одиночное наследование. Вы можете объединить ваши классы в цепочку (т.е. MembershipUser наследует от ProfileBase ) или использовать interfaces .

    
ответ дан Jamie Ide 04.02.2010 в 16:59
2

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

Во втором случае вы пытаетесь унаследовать от ProfileBase и MembershipUser , что не разрешено компилятору. Лучший способ обойти это - инкапсулировать один (или оба) из ProfileBase и MembershipUser .

    
ответ дан Jeff Hornby 04.02.2010 в 17:02
1

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

В первом примере вы наследуете от ProfileBase и объявляете, что ваш класс реализует интерфейс ISessionMgrEntry .

Вы можете добавить столько классов в класс, сколько захотите (при условии, что вы реализуете их все).

    
ответ дан Oded 04.02.2010 в 16:58
0

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

Например, IEnumerable<T> наследует IEnumerable , и оба предоставляют метод GetEnumerator() с различными типами возврата. Следовательно, IEnumerable.GetEnumerator() , как правило, реализуется явно:

class Foo : IEnumerable<object>{
    // explicitly implement IEnumerable.GetEnumerator()
    IEnumerator IEnumerable.GetEnumerator ()
    {
        return GetEnumerator();
    }

    public IEnumerator<object> GetEnumerator ()
    {
        yield break;
    }
}

Вызов GetEnumerator() в IEnumerable.GetEnumerator() не является бесконечно рекурсивным вызовом; он вызывает открытый элемент с тем же именем, не сам (т.е. метод IEnumerable.GetEnumerator() ).

    
ответ дан jonp 05.02.2010 в 19:09
  • спасибо человеку - это разобрало его для меня. очень признателен! –  Peter 05.02.2010 в 21:00