C# 从具有继承接口的父级实现继承接口

C# 从具有继承接口的父级实现继承接口,c#,inheritance,interface,C#,Inheritance,Interface,假设我有以下3个接口(格式设计为简洁): 我有二级和三级类,它们继承各自的接口(格式设计是为了简洁): 我希望能够将实现的类实现到实现两个接口的根类中,类似于: public class Root : IRoot { public Secondary secondary { get; set; } public Tertiary tertiary { get; set; } public string foo { get; set; } // This wouldn't

假设我有以下3个接口(格式设计为简洁):

我有二级和三级类,它们继承各自的接口(格式设计是为了简洁):

我希望能够将实现的类实现到实现两个接口的根类中,类似于:

public class Root : IRoot
{
    public Secondary secondary { get; set; }
    public Tertiary tertiary { get; set; }
    public string foo { get; set; } // This wouldn't need to be cross-compatible
}

public class Root2 : IRoot
{
    public Secondary2 secondary { get; set; }
    public Tertiary2 tertiary { get; set; }
    public double bar { get; set; } // This wouldn't need to be cross-compatible either
}
然后我想做一些类似的事情(对不起,反思不是我的强项):

这样IRoot的所有成员都从根转移到根2

在C#中执行此操作将导致匹配类型错误(CS0738)

换句话说(如果这很难理解的话,我很抱歉)我希望我的根接口使用HAS-A关系中的第二和第三接口的签名,我的IRoot接口将具有这种关系,但是在实现根类时,我也希望实现它们各自的继承类,并且不必使用实际的接口


感谢您抽出宝贵的时间。

由于
Root
实现了
IRoot
并且
IRoot
需要接口类型的属性,您必须
Root
中将这些属性声明为接口

public class Root : IRoot
{
    public ISecondary secondary { get; set; }
    public ITertiary tertiary { get; set; }
}
这仍然允许您为它们分配类

IRoot root = new Root {
    secondary = new Secondary(),
    tertiary = new Tertiary()
};
如果出于某种原因,您希望访问不属于
IsSecondary
接口的
次要
对象的成员,可以这样做:

var secondary = root.secondary as Secondary;
if (secondary != null) {
    secondary.DoSomething();
}

另一种方法是使用泛型和泛型类型约束

public interface IRoot<TSecondary, TTeritary>
    where TSecondary : ISecondary
    where TTeritary : ITertiary
{
    public TSecondary secondary
    public TTeritary tertiary
}
现在你可以这样做了

var list = new List<IRoot<ISecondary, ITertiary>>();
list.Add(new Root());
list.Add(new Root2());
var list=newlist();
添加(新根());
添加(newroot2());

由于
Root
实现了
IRoot
并且
IRoot
需要接口类型的属性,因此必须在
Root
中将这些属性声明为接口

public class Root : IRoot
{
    public ISecondary secondary { get; set; }
    public ITertiary tertiary { get; set; }
}
这仍然允许您为它们分配类

IRoot root = new Root {
    secondary = new Secondary(),
    tertiary = new Tertiary()
};
如果出于某种原因,您希望访问不属于
IsSecondary
接口的
次要
对象的成员,可以这样做:

var secondary = root.secondary as Secondary;
if (secondary != null) {
    secondary.DoSomething();
}

另一种方法是使用泛型和泛型类型约束

public interface IRoot<TSecondary, TTeritary>
    where TSecondary : ISecondary
    where TTeritary : ITertiary
{
    public TSecondary secondary
    public TTeritary tertiary
}
现在你可以这样做了

var list = new List<IRoot<ISecondary, ITertiary>>();
list.Add(new Root());
list.Add(new Root2());
var list=newlist();
添加(新根());
添加(newroot2());

好的,要实现接口,您必须使用相同的类型,但您可以保留更具体的实现并显式实现接口属性:

public class Root : IRoot
{
    public Secondary secondary { get; set; }
    public Tertiary tertiary { get; set; }
    public string foo { get; set; } // This wouldn't need to be cross-compatible

    ISecondary IRoot.secondary {get {return this.secondary;} set{;}}
    ITertiary IRoot.tertiary {get {return this.tertiary;} set{;}}
}
这样,您就可以以类型安全的方式使用更多sepcific类型,而无需强制转换。然而,问题在于
二级
三级
的设置器。由于可以传入任何
IsSecondary
,因此无法保证传入的对象是
次要的
,因此无法安全地将其分配给
次要的
属性。你的选择是:

  • 强制转换到一个
    辅助
    ,如果它不是该类型,则会引发异常
  • 确定是否可以强制转换到辅助,如果不能,则执行其他操作
  • IRoot
    get-only中设置属性

好的,要实现接口,您必须使用相同的类型,但您可以保留更具体的实现并显式实现接口属性:

public class Root : IRoot
{
    public Secondary secondary { get; set; }
    public Tertiary tertiary { get; set; }
    public string foo { get; set; } // This wouldn't need to be cross-compatible

    ISecondary IRoot.secondary {get {return this.secondary;} set{;}}
    ITertiary IRoot.tertiary {get {return this.tertiary;} set{;}}
}
这样,您就可以以类型安全的方式使用更多sepcific类型,而无需强制转换。然而,问题在于
二级
三级
的设置器。由于可以传入任何
IsSecondary
,因此无法保证传入的对象是
次要的
,因此无法安全地将其分配给
次要的
属性。你的选择是:

  • 强制转换到一个
    辅助
    ,如果它不是该类型,则会引发异常
  • 确定是否可以强制转换到辅助,如果不能,则执行其他操作
  • IRoot
    get-only中设置属性

您能解释一下为什么要这样做吗?我正在尝试开发一个“接口层次结构”,这样我就可以设计数据模型模板,并轻松地跨实现该接口的不同类类型移动数据。这有意义吗?
IRoot的实现是否不止一个?
IRoot
的消费者将如何使用它?Yacoub:是的,IRoot将有多个实现。设想两个数据模型是交叉兼容的。一个实现可以是包含部分数据的模板,而另一个具有更多变量的实现可以从中获取信息。很抱歉。我不明白你想做什么。我帮不上忙。你能解释一下为什么要这么做吗?我正在尝试开发一个“接口层次结构”,这样我就可以设计数据模型模板,并轻松地在实现该接口的不同类类型之间移动数据。这有意义吗?
IRoot的实现是否不止一个?
IRoot
的消费者将如何使用它?Yacoub:是的,IRoot将有多个实现。设想两个数据模型是交叉兼容的。一个实现可以是包含部分数据的模板,而另一个具有更多变量的实现可以从中获取信息。很抱歉。我不明白你想做什么。我没办法。仿制药是天才的杰作。谢谢我将尝试一下,看看它是否与我的程序一起工作。是的!工作得很有魅力!仿制药是一种天才之举。谢谢我将尝试一下,看看它是否与我的程序一起工作。是的!工作得很有魅力@Stanley-对于这种显式接口属性声明的特殊方法,您有什么好的文档吗?我想了解更多。我已经看过了,它演示了成员的显式声明,在本例中是方法。你有关于属性的更详细的资料吗?@D Stanley-你有关于这种特殊解释方法的好文档吗