C#泛型转换

11

我有一个名为IEditor的接口。

public interface IEditor<T> 
    where T: SpecialObject

SpecialObject 是一个抽象类。

以下是我的问题:

我有一个继承自 SpecialObject 的类和一个实现了 IEditor 接口的视图。

public class View : IEditor<Person>

现在,我需要检查View是否实现了IEditor<SpecialObject>
Boolean isEditor = View is IEditor<SpecialObject>

但是 IEditor 总是为 false

有没有可能检查视图是否为 IEditor<SpecialObject>

编辑

我有一个方法,当关闭事件被触发时会调用它。传递给该方法的视图可以实现 IEditor,但它们也可以实现另一个接口,例如 IView。

  void Closing(object sender, MyEventArgs e)
  {
      if(e.Item is IView)
      {
          // DO some closing tasks

          if(e.Item is IEditor<SpecialObject>)          // always false
          {
              // Do some special tasks
              var editor = e.Item as IEditor<SpecialObject>;

              var storedEditObect = editor.StoredObject;

              // more tasks
          }
      } else if(e.Item is ISomeOtherView)
      {}
  }

我有一些类,如Person、Address等,它们都继承自SpecialObject。在某些情况下,e.Item可能会继承自IEditor或IEditor。 因此,我必须将其转换为基类才能访问默认属性字段。


1
尝试使用 "as" 关键字并检查是否为 null。如果不是 null,则为所需类型。 - Tigran
2
@Tigran isas 具有相同的基础机制。问题在于 IEditor<Person> 并没有继承自 IEditor<SpecialObject> - dlev
你可以添加 IEditor 接口作为 IEditor<T> 的基础。然后你可以检查 View is IEditor - Piotr Auguscik
“View”是一种类型的名称……你不能像这样使用它与“is”一起,因为那需要一个。例如,您是否有一个类型为View的变量?一个简短但完整的演示问题的程序将非常有用。我猜这是一个通用的变异问题,但现在很难说。 - Jon Skeet
1
@Cr3at0rX:如果您提供准确的示例,那真的会很有帮助。最好是完整的示例。如果某个东西旨在演示一个观点,那么它确实能够演示出来,而不仅仅是不准确的语法... - Jon Skeet
显示剩余2条评论
2个回答

12
创建一个非泛型的基础接口。例如:
public interface IEditor {}

public interface IEditor<T> : IEditor ... {}

然后检查 IEditor


我通常不喜欢标记接口,但这个实际上非常好。加一分! - dlev
很遗憾,这对我不起作用,因为我还必须转换视图对象。 - Cr3at0rX
@Cr3at0rX:转换成什么?你目前的要求非常模糊。 - Jon Skeet

11
你的问题是泛型方差。例如,IList<MemoryStream> 不是 IList<Stream>
从C# 4开始,你可以通过以下方式潜在地使你的接口协变
public interface IEditor<out T> where T: SpecialObject

在那时,一个 IEditor<Person> 将会成为一个 IEditor<SpecialObject> - 但是这只有在你的接口只在“out”位置使用 T 时才能起作用。

如果对你来说这是可行的,那么它可能比 leppie 的非泛型基础接口更加清晰明了 - 但当协变不合适时,这是一个很好的替代方案。


很不幸,这对我也行不通,因为 T 不仅仅是一个返回类型。 还有其他可能性吗? - Cr3at0rX
@Cr3at0rX:你明白为什么它对你不起作用吗?你不能简单地将对象用作IEditor<SpecialObject>,因为这样做会违反类型安全性。如果您可以提供更完整的示例以说明您要尝试的操作,我们可能能够为您提供更多帮助。 - Jon Skeet
@Cr3at0rX:好的,看起来你可能会有一个包含只有“out”部分的协变基接口,然后是扩展该接口而不是协变的接口。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接