我有这样的事情:
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
}
}
。以下是代码:
/usr/local/bin/
提前致谢。
答案 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
一致,因此这是指示功能可以正确的地方被覆盖。