12

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

例如

public interface IShape
{
    int area { get; }
}

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

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

IE,

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

4 回答 4

27

There's no concept of optional members of an interface.

What you need here is to define two interfaces. One contains area, and the other contains WindowName. Something like this:

public interface IShape
{
    int area { get; }
}

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

Then the implementing classes can choose to implement either IShape or IFindWindow.

At runtime you simply use the is operator to determine whether or not IFindWindow is implemented by the object at hand.

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

And to actually use the more derived interface use the as operator:

IShape shape = ...;
IFindWindow findWindow = shape as IFindWindow;
if (findWindow != null)
    string windowName = findWindow.WindowName;
于 2013-07-25T10:14:01.360 回答
9

You can create a new interface that those shapes that wish to use the option would derive from instead:

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

And so, if you're passed an IShape, you can now attempt a cast to the IWindowedShape to be able to access this optional property.

public void DoStuff(IShape shape)
{
   var windowed = shape as IWindowedShape;
   string windowName = null;
   if(windowed!=null)
   {
      windowName = windowed.WindowName;
   }
}
于 2013-07-25T10:13:50.390 回答
6

No, this is not possible. If you derive from interface, you must define all its members in derived class.

To achieve what you want you may think about using Abstract classes.

Example of use case:

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
}

if on other hand you need destict separation, define multiple interfaces, with different ptoperties and derive from appropriate interface when needed.

于 2013-07-25T10:14:06.563 回答
3

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

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

public interface IShape
{
    int area { get; }
}

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

您的新类将实现IShapeEx,而您的“旧类”仍将实现IShape.

于 2013-07-25T10:19:17.537 回答