【问题标题】:Class method that is not in the interface不在接口中的类方法
【发布时间】:2013-07-28 21:41:42
【问题描述】:

我有一个简单的 c# 问题(所以我相信)。我是该语言的初学者,我遇到了有关实现它们的接口和类的问题。问题是

我有接口iA

interface iA
{
  bool method1
  bool method2
  bool method3
}

以及实现该接口的 3 个类:BCD

class B : iA
{
  public bool method1
  public bool method2
  public bool method3
}

如果 B 类有另一个不在接口中的方法,比如说method4(),我有以下内容:

iA element = new B();

然后我会使用:

element.method4();

我会收到一条错误消息,指出我没有采用iA 类型的第一个参数的method4()

问题是:我能否拥有一个接口类型的对象并用一个类进行实例化,并让该对象从该类调用一个方法,一个不在接口中的方法?

我想出的一个解决方案是在接口和派生类之间使用一个抽象类,但是 IMO 会使接口超出范围。在我的设计中,我只想使用接口和派生类。

【问题讨论】:

  • if(element is typeof(B)) ((B)element).method4(); 这应该会有所帮助
  • 一个新用户提出了一个清晰且格式正确的问题。这是罕见的,恭喜并欢迎。 :)
  • 好问题。 +1 如果您提供真实场景,我们可以建议最佳设计方法。

标签: c# methods interface


【解决方案1】:

是的,这是可能的。您只需要将接口类型转换为类类型,如下所示:

iA element = new B();
((B)element).method4();

按照 wudzik 的建议,您应该检查 elemnt 的类型是否正确:

if(element is B)
{
    ((B)element).method4();
}

【讨论】:

  • 旁注:您可以添加if(element is typeof(B))以确保该元素为B
  • 你可能不想这样做?
  • @Sam Leach:你为什么不想这样做?这是一项常见的任务
  • is keyword 不能这样工作,您需要if(element is B) 才能使其工作
  • @user2629277 - 听起来您将只想通过接口工作的代码混合在一起(应该适用于BCD 或任何其他实现)和代码它特别“知道”它正在使用B。这通常表明设计有些混乱。
【解决方案2】:

不用强制转换你也可以这样做。

interface iA
{
  bool method1();
  bool method2();
  bool method3();
}

interface IFoo : iA
{
  bool method4();
}

class B : IFoo
{
  public bool method1() {}
  public bool method2() {}
  public bool method3() {}
  public bool method4() {}
}

IFoo element = new B();    
element.method4();

注意:尝试在 C# 接口中使用大写的 I 前缀。

【讨论】:

  • 这避免了类型检查和强制转换,但现在你有了一个不同的对象,IFoo。如果用户有一个 iA 对象,仍然需要检查该对象是否是一个 IFoo(并强制转换),以便能够运行 method4。
  • 是的,但是从设计角度来说,处理这样的接口比处理具体类型更聪明。这是一种可扩展性更好的解决方案,因为现在可以更轻松地扩展实现各种接口的类型。
【解决方案3】:

你必须将接口类型转换为类类型;通常我们通过 as 来实现:

  B b = element as B; // <- try cast element as B

  if (!Object.RefernceEquals(null, b)) { // <- element is B or can be legaly interpreted as B
    b.method4(); 
  }

“as”的优点是只有一次转换操作,而“is”和(B)必须进行两次转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-07
    • 2015-07-09
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多