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

17

У меня есть несколько вопросов, связанных с дизайном моего класса 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 ответов

29

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

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
5

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

    
ответ дан nWorx 04.02.2010 в 16:59
источник
3

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

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

C # поддерживает только одно наследование. Вы можете либо объединить свои классы (т. Е.% Co_de% наследует от MembershipUser ), либо использовать ProfileBase .

    
ответ дан 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() не является бесконечно рекурсивным вызовом; он вызывает публичный член с тем же именем, not сам (т. е. метод IEnumerable.GetEnumerator() ).

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