具有通用覆盖的接口

时间:2015-11-10 08:43:29

标签: c# interface

我有这样的事情:

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

public class ImplicitClientB : ImplicitClientA, IGenericItems<IGenericItemC>

我希望在课程IGenericItems<IGenericItemA>中覆盖IGenericItems<IGenericItemB>ImplicitClientB

哪种方式最好?

  • ImplicitClientAImplicitClientB中创建虚拟保护方法 在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 } }

以下是代码:

/usr/local/bin/

提前致谢。

2 个答案:

答案 0 :(得分: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中将其声明为虚拟并覆盖它。或者使用我之前提到的虚拟保护方法。

但是为了更改IGenericItems<IGenericItemB>继承的ImplicitClientA的实施,我必须在IGenericItems<IGenericItemB>中明确实施ImplicitClientB

所以我只能用一种方式来引用它:

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

所以一切正常,每个人都很开心!

答案 1 :(得分: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一致,因此这是指示功能可以正确的地方被覆盖。