2015-11-10 37 views
0

我有這樣的事情:接口方面採用通用的覆蓋

public class ImplicitClientA : IGenericItems<IGenericItemA>, IGenericItems<IGenericItemB> 

public class ImplicitClientB : ImplicitClientA, IGenericItems<IGenericItemC> 

,我想重寫IGenericItems<IGenericItemA>IGenericItems<IGenericItemB>ImplicitClientB類。

哪一個是最好的方法?

  • 要創建ImplicitClientA一個虛擬的保護方法和 覆蓋它在ImplicitClientB。或...
  • 要明確執行IGenericItems<IGenericItemA>IGenericItems<IGenericItemB>在類ImplicitClientB

下面是代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace CSharpConsoleApplication.Tests 
{ 
    public class InterfacesTest 
    { 
     public static void Run() 
     { 
      var implA = new ImplicitClientA(); 
      IGenericItems<IGenericItemA> implA1 = implA; 
      IGenericItems<IGenericItemB> implA2 = implA; 

      Console.WriteLine("Text value for a is: " + implA1.Items.ToList()[0].GetTextValue()); 
      Console.WriteLine("Number value for a is: " + implA2.Items.ToList()[0].GetNumberValue()); 
      Console.WriteLine(); 

      var implB = new ImplicitClientB(); 
      IGenericItems<IGenericItemA> implB1 = implB; 
      IGenericItems<IGenericItemB> implB2 = implB; 
      IGenericItems<IGenericItemC> implB3 = implB; 

      Console.WriteLine("Text value for b is: " + implB1.Items.ToList()[0].GetTextValue()); 
      Console.WriteLine("Number value for b is: " + implB2.Items.ToList()[0].GetNumberValue()); 
      Console.WriteLine("Date value for b is: " + implB3.Items.ToList()[0].GetDateValue()); 
      Console.WriteLine(); 
     } 
    } 



    // Interfaces 

    public interface IGenericItem 
    { 
     int Id { get; set; } 
    } 

    public interface IGenericItemA : IGenericItem 
    { 
     string GetTextValue(); 
    } 

    public interface IGenericItemB : IGenericItem 
    { 
     int GetNumberValue(); 
    } 

    public interface IGenericItemC : IGenericItem 
    { 
     DateTime GetDateValue(); 
    } 


    public interface IGenericItems<T> 
    { 
     IEnumerable<T> Items { get; } 
    } 


    // Classes 

    public class ConcreteA : IGenericItemA 
    { 
     public ConcreteA(int id) 
     { 
      Id = id; 
     } 

     #region IGenericItemA Members 

     public string GetTextValue() 
     { 
      return Id.ToString(); 
     } 

     #endregion 

     #region IGenericItem Members 

     public int Id { get; set; } 

     #endregion 
    } 

    public class ConcreteB : IGenericItemB 
    { 
     public ConcreteB(int id) 
     { 
      Id = id; 
     } 

     #region IGenericItemB Members 

     public int GetNumberValue() 
     { 
      return Id + 1; 
     } 

     #endregion 

     #region IGenericItem Members 

     public int Id { get; set; } 

     #endregion 
    } 

    public class ConcreteC : IGenericItemC 
    { 
     public ConcreteC(int id) 
     { 
      Id = id; 
     } 

     #region IGenericItemC Members 

     public DateTime GetDateValue() 
     { 
      return DateTime.Now; 
     } 

     #endregion 

     #region IGenericItem Members 

     public int Id { get; set; } 

     #endregion 
    } 


    // Implicit interfaces implementation 

    public class ImplicitClientA : IGenericItems<IGenericItemA>, IGenericItems<IGenericItemB> 
    { 

     #region IGenericItems<IGenericItemA> Members 

     public IEnumerable<IGenericItemA> Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemA>(); 
       collection.Add(new ConcreteA(1)); 
       return collection; 
      } 
     } 

     #endregion 

     #region IGenericItems<IGenericItemB> Members 

     IEnumerable<IGenericItemB> IGenericItems<IGenericItemB>.Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemB>(); 
       collection.Add(new ConcreteB(1)); 
       return collection; 
      } 
     } 

     #endregion 
    } 

    public class ImplicitClientB : ImplicitClientA, IGenericItems<IGenericItemC> 
    { 
     #region IGenericItems<IGenericItemC> Members 

     public new IEnumerable<IGenericItemC> Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemC>(); 
       collection.Add(new ConcreteC(2)); 
       return collection; 
      } 
     } 

     #endregion 
    } 


    // Explicit interfaces implementation 
    public class ExplicitClientA : IGenericItems<IGenericItemA>, IGenericItems<IGenericItemB> 
    { 
     #region IGenericItems<IGenericItemA> Members 

     IEnumerable<IGenericItemA> IGenericItems<IGenericItemA>.Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemA>(); 
       collection.Add(new ConcreteA(1)); 
       return collection; 
      } 
     } 

     #endregion 

     #region IGenericItems<IGenericItemB> Members 

     IEnumerable<IGenericItemB> IGenericItems<IGenericItemB>.Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemB>(); 
       collection.Add(new ConcreteB(1)); 
       return collection; 
      } 
     } 

     #endregion 
    } 

    public class ExplicitClientB : ImplicitClientA, IGenericItems<IGenericItemB>, IGenericItems<IGenericItemC> 
    { 
     #region IGenericItems<IGenericItemB> Members 

     IEnumerable<IGenericItemB> IGenericItems<IGenericItemB>.Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemB>(); 
       collection.Add(new ConcreteB(2)); 
       return collection; 
      } 
     } 

     #endregion 

     #region IGenericItems<IGenericItemC> Members 

     IEnumerable<IGenericItemC> IGenericItems<IGenericItemC>.Items 
     { 
      get 
      { 
       var collection = new List<IGenericItemC>(); 
       collection.Add(new ConcreteC(2)); 
       return collection; 
      } 
     } 

     #endregion 
    } 
} 

在此先感謝。

回答

1

我想通了。 答案是否定的。例如ImplicitClientA實施IGenericItems<IGenericItemA>IGenericItems<IGenericItemB>

只有其中一個可以隱式聲明。另一個必須明確聲明。我想第一個就像裝修類的東西。

對於第一個我可以聲明該方法爲虛擬的,並在子類ImplicitClientB中覆蓋它,或者我可以使用虛擬保護方法並在子類ImplicitClientB中覆蓋此方法。

所以對於ImplicitClientA可以參考我Items都喜歡:

var implA = new ImplicitClientA(); 
var x = implA.Items; 

IGenericItems<IGenericItemA> implA = new ImplicitClientA(); 
var x = implA.Items; 

,但如果我想使用IGenericItems<IGenericItemB>的唯一途徑是

IGenericItems<IGenericItemB> implA = new ImplicitClientA(); 
var x = implA.Items; 

現在爲孩子類ImplicitClientB

如果我想爲IGenericItems<IGenericItemA>Items做別的事情,我所要做的就是在ImplicitClientA中聲明它爲虛擬的並覆蓋它。或者使用前面提到的虛擬保護方法。

但爲了更改由ImplicitClientA繼承的IGenericItems<IGenericItemB>的實現,我必須在ImplicitClientB中明確實施IGenericItems<IGenericItemB>

所以我可以引用它只有一個辦法:

IGenericItems<IGenericItemB> implB = new ImplicitClientB(); 
var x = implB.Items; 

所以一切工作,每個人都快樂!

0

我不會明確地實現接口。

他們已經被ImplicitClientA實現的,所以如果你做你必須要非常小心,你怎麼稱呼你的方法(A隱含實現一個接口,B明確地實現它):

B b = new B(); 
b.Method();    // calls the method defined in A 
((A)b).Method();   // calls the method defined in A 
((IInterface)b).Method(); // calls the method defined in B 

我認爲的責任實施IGenericItems<IGenericItemA>接口與ImplicitClientA,所以這是表明功能可以被覆蓋的正確位置。