如何强制多个接口包含相同的属性?

时间:2010-03-25 03:33:43

标签: c# inheritance properties interface

我试图找出一种方法来强制我的所有接口都包含相同名称/类型的属性。

例如:我有两个接口; IGetAlarms和IGetDiagnostics。每个接口都将包含特定于接口本身的属性,但是我想强制两个接口(以及稍后可能添加的所有其他接口)包含相同名称的属性。所以,结果可能看起来像这样:

interface IGetAlarms
{
    string GetAlarms();
    DateTime LastRuntime { get; set; }
}

interface IGetDiagnostics
{
    string GetDiagnostics();
    DateTime LastRuntime { get; set; } 
}

请注意,两个接口都包含名为LastRuntime的DateTime属性。

我想知道是否有某种方法可以强制稍后添加的其他接口包含DateTime LastRuntime属性。我天真地试图让我的所有接口实现另一个接口(IService) - 其中包括LastRuntime属性。但是,这并没有解决我的问题,因为它只是强制类实现属性 - 而不是所有的接口。

感谢。

3 个答案:

答案 0 :(得分:4)

接口可以从其他接口继承。

interface IDerived : IBase
{
    string Foo { get; set; }
}

interface IBase
{
    DateTime LastRunDate { get; set; }
}

任何来自IDerived的类都必须实现IBase的方法/属性。

class Derived : IDerived 
{
    #region IDerived Members

    public string Foo { get; set; }

    #endregion

    #region IBase Members

    public DateTime LastRunDate {get;set;}

    #endregion
}

答案 1 :(得分:1)

如果我正确理解你的问题,你想强制一个类实现许多不同的接口,接口列表会随着时间的推移而增长,但会有一些共同的属性。

您使用IService界面解决的公共属性部分。像这样的东西,我猜是

interface IService
{
    DateTime LastRuntime { get; set; }
}

interface IGetAlarms : IService
{
    string GetAlarms();

}

interface IGetDiagnostics : IService
{
    string GetDiagnostics();
}

一个类必须实现的不断增加的接口列表也可以以类似的方式解决。创建一个“复合”接口,它继承了您希望类实现的所有接口

interface IComposite : IGetAlarms, IGetDiagnostics {}

class MyClass : IComposite
{
    ...
}

当你让IComposite接口继承一个新接口时,该类也将实现新接口。

修改

回应你的澄清;在这种情况下,您不应该共享LastRuntim e属性的规范,而是在每个单独的接口中声明它。在实现类中,您可以使用Explicit interface member implementation

class MyClass : IComposite
{
    DateTime IGetAlarms.LastRuntime { get; set; }
    DateTime IGetDiagnostics.LastRuntime { get; set; }
    ...
}

但是,AFAIK无法强制实现类显式实现每个单独的接口

答案 2 :(得分:0)

这实际上取决于您需要接口的确切内容。您可以使用泛型来强制执行指定的模式,但如果它们都具有相同的签名,则无法单独强制执行每个模式。

public interface IA<T> where T: class
{
    void DoIt(T ignore = null);
}
public interface IB : IA<IB>
{
}
public interface IC : IA<IC>
{
}

这将强制以下类分别实现每个:

public class D : IB, IC
{
    public void DoIt(IB ignore = null) { }
    public void DoIt(IC ignore = null) { }
}

这是“T ignore”参数,它强制每个人单独实现,并且因为它有一个默认值,你可以忽略该参数,除非使用反射调用它。

但显然这不适用于属性,因此必须使用getter / setter方法实现它们。