2010-02-04 59 views
17

我有幾個問題涉及到我的User類的設計,但 他們是不同的,我認爲他們應該是獨立的 問題。試圖繼承三個基類,不能

所以,第一個涉及基類的繼承。我目前 繼承兩個類,ProfileBaseISessionMgrEntry這樣:

public class User : ProfileBase, ISessionMgrEntry 

但是,我也想繼承第三類,MembershipUser,像這樣:

public class User : ProfileBase, MembershipUser, ISessionMgrEntry 

但是,編譯韓元」讓我這樣做。爲什麼?而且,我該如何獲得 ?

謝謝。

PS - ASP.NET 3.5/C#

編輯

嗨。我認爲下面的解決方案可能適用於我試圖達到的目標。看起來非常簡單直接。我正在這樣做,因此我可以創建一個完整/組合的User對象。有人認爲這可能導致問題的原因嗎?我在做這件事的時候出現了一個重疊的屬性。例如,MembershipUserProfileBase共享「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; } 
     } 

     .... 

    } 
+0

爲什麼當你在道具上做'as'? – ChaosPandion 2010-02-05 18:12:36

+0

你說得對,我以爲這是脫口而出。我遵循這個約定,但意識到它的不同情況: [SettingsAllowAnonymous(false),CustomProviderData(「IPAddress; string」)] public string IPAddress {get {return base [「IPAddress」] as string; } set {base [「IPAddress」] = value; }} – 2010-02-05 19:05:21

回答

28

在第一個例子中,你實際上並不是從兩個類繼承,而是從一個類和一個接口繼承。

C#不允許從類繼承多重繼承,但確實允許實現多個接口。有關更多信息,請參閱this MSDN blog post

您將不得不製作一個IMembershipUser界面,並在User類中實現該界面。

接口通常以基於具有I前綴的具體類名稱命名。所以類MembershipUser將有一個接口IMembershipUser。沒有什麼能阻止你使用其他名字,但每個使用接口的人都習慣於這個命名約定。

+0

謝謝克里斯。 你有空可以看看我的編輯嗎?再次感謝你的幫助。 – 2010-02-05 18:00:06

+1

@Code Sherpa - 我真的需要看到更多的代碼,並且可以通過SO進行更多的對話,但是如果你有重複的屬性,你應該看看不同的類層次結構。感謝的人 - – ChrisF 2010-02-05 18:14:27

1

C#不支持多繼承。

在第一個示例中,您繼承ProfileBase並聲明您的類正在實現ISessionMgrEntry接口。

您可以根據需要添加儘可能多的接口(只要您全部實現它們即可)。

3

C#只支持單繼承。您可以將您的班級鏈接在一起(即MembershipUser繼承自ProfileBase)或使用interfaces

5

在C#中你才能從一個類繼承,但只要你想實現儘可能多的接口。 你的情況ProfileBaseMembershipUser是類,ISessionMgrEntry是一個接口。

2

C#只允許單繼承:你只能從一個基類繼承。在第一種情況下,ISessionMgrEntry是一個與基類不同的接口。這裏有區別的好文章:http://msdn.microsoft.com/en-us/library/ms973861.aspx

在你正試圖從兩個ProfileBaseMembershipUser,該編譯器將不允許繼承第二種情況。解決此問題的最佳方法是封裝ProfileBaseMembershipUser之一(或兩者)。

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()方法)。

+0

- 爲我整理出來的。非常感激! – 2010-02-05 20:00:11