C#接口创建Optional属性

时间:2013-07-25 10:10:23

标签: c# interface

我有用C#编写的接口,它已经由类实现了。是否有可能在界面中添加一个属性作为可选项而不修改现有的实现类?

E.g

public interface IShape
{
    int area { get; }
}

public class FindWindow : IShape
{
    public int area
    {
        get
        {
            return 10;
        }
    }
}

在这个FindWindow中已经写好了。是否可以添加一个可选属性而不在现有类中实现。

public interface IShape
{
    int area { get; }
    //optional
    //string WindowName{get;}
}

public class FindWindow : IShape
{
    public int area
    {
        get
        {
            return 10;
        }
    }

    //WindowName i am not implementing here
}

public class FindWindowName : IShape
{
    public int area
    {
        get { return 20; }
    }

    public string WindowName
    {
        get { return "Stack Overflow"; }
    }
}

4 个答案:

答案 0 :(得分:23)

接口的可选成员没有概念。

这里需要的是定义两个接口。一个包含area,另一个包含WindowName。像这样:

public interface IShape
{
    int area { get; }
}

public interface IFindWindow: IShape
{
    string WindowName { get; }
}

然后,实现类可以选择实现IShapeIFindWindow

在运行时,您只需使用is运算符来确定当前对象是否实现了IFindWindow

IShape shape = ...;
if (shape is IFindWindow)
    ....

要实际使用更多派生的界面,请使用as运算符:

IShape shape = ...;
IFindWindow findWindow = shape as IFindWindow;
if (findWindow != null)
    string windowName = findWindow.WindowName;

答案 1 :(得分:7)

您可以创建一个新界面,以便那些希望使用该选项的形状来自:

public interface IWindowedShape : IShape
{
    string WindowName{get;}
}

因此,如果您通过了IShape,您现在可以尝试转换为IWindowedShape,以便访问此可选属性。

public void DoStuff(IShape shape)
{
   var windowed = shape as IWindowedShape;
   string windowName = null;
   if(windowed!=null)
   {
      windowName = windowed.WindowName;
   }
}

答案 2 :(得分:4)

不,这是不可能的。如果从派生派生,则必须在派生类中定义其所有成员。

要实现您的目标,您可以考虑使用Abstract类。

用例示例:

public abstract class Base {
    public abstract Name {get;set;} // MUST DEFINE IN DERIVED CLASS, LIKE INTERFACE

    public string Surname {get;set;} // JUST A SIMPLE PROPERTY OF A BASE CLASS
}

如果另一方面你需要destict分离,定义多个interfaces,具有不同的ptoperties并在需要时从适当的接口派生。

答案 3 :(得分:2)

您必须实现所有提供的方法和/或属性,这是接口的本质。

在您的情况下,您可以创建一个新的第二个接口,它继承自原始接口:

public interface IShape
{
    int area { get; }
}

public interface IShapeEx : IShape
{
    string WindowName { get; }
}

您的新课程将实施IShapeEx,而您的“遗产课程”仍会实施IShape