我不确定如何提出这个问题.假设我有一个类需要访问Control的某些属性(例如,Visible和Location).也许我想使用同一个类来访问具有相同名称的另一个项的属性,但该类可能不是从Control派生的.所以我尝试制作一个界面:
public interface IThumbnail {
bool Visible { get; set; }
int Height { get; set; }
int Width { get; set; }
Image Image { get; set; }
Point Location { get; set; }
event EventHandler Click;
}
Run Code Online (Sandbox Code Playgroud)
请注意,例如,PictureBox碰巧实现了此接口.但是,因为类定义没有说它实现了IThumbnail,所以我无法将PictureBoxes转换为IThumbnails - 我在运行时得到了InvalidCastException.但是为什么CLR不能"弄清楚"PictureBox确实实现了IThumbnail(它只是没有明确地说它确实如此).
另外,我该怎么做才能处理这种情况?我想要一种方法来访问一些 PictureBox的属性,而不让我的类知道它正在修改PictureBox.
谢谢,山姆
PS-我是接口编程的新手,所以如果这是一个愚蠢的问题我很抱歉.
这不是一个愚蠢的问题,它是一个很好的问题.:)
你在界面上要求的通常被称为" 鸭子打字".它目前不受支持,但C#4.0将通过新的" dynamic"关键字支持它.
在这一点上,你真的有三个选择我知道:
您可以上到树,直到找到共同的祖先(可能Component),然后向下转换为您支持的类型.如果堕落失败,你可以适当地投掷或处理.
Pro:最小代码重复.
Con:对于运行时类型的安全性,您正在远离编译时类型安全性.您必须为无效的强制转换添加错误检查/处理.
码:
public void UseThumbnail(Component c)
{
PictureBox p = c as PictureBox;
if(p != null) // do whatever
// so forth
}
Run Code Online (Sandbox Code Playgroud)您可以根据实现此功能所需的所有内容复制功能.
Pro:保持编译时类型安全
Con:你正在复制不同类型的代码.这可能会成为一个重大的维护负担,特别是如果您处理两个以上类似的类.
码:
public void UsePictureBox(PictureBox p)
{
// Some code X
}
public void UseOtherControl(OtherControl p)
{
// Some code X
}
Run Code Online (Sandbox Code Playgroud)您可以创建特殊接口并为要支持的类创建子类,以公开该常用功能.
Pro:您可以获得编译时安全性并可以针对您的新界面进行编程.
Con:您必须为要处理的所有内容添加一个空子类,并且需要使用它们.
码:
public class ThumbnailPictureBox : PictureBox, IThumbnail
{ }
Run Code Online (Sandbox Code Playgroud)