【问题标题】:C# - Passing a inherited class through a parameterC# - 通过参数传递继承的类
【发布时间】:2014-12-25 03:36:36
【问题描述】:

我有一个场景,我希望能够通过方法参数传递一个类,并从传递的类的实例中获取特定于类的信息。

例子:

public abstract class Foo {
   public int x;
}

然后

public class Bar : Foo {
    public int y;
    public Bar(int y) {
        this.y = y;
    }
}

我需要做的是这样的事情

public void foobar(Foo f) {
    int y = f.y;
}

会这样调用:

foobar(new Bar(5));

这将获得一个特定于“继承”类 Foo 的类“Bar”的值。

我需要能够在不进行类型转换的情况下执行此操作,以便动态处理该类。

我知道我只能说

((Bar)f).y

但是,关键是我将传递多个类,并且静态类型转换会破坏目的。

【问题讨论】:

  • 那为什么不在 Foo 中定义 y 呢?特别是如果您要尝试在任何继承的类中获取 y 值。
  • 但是它打败了面向对象的编程。你不能用y属性准备接口f.e IBar吗?
  • 查看 MSDN 的“标识符模式”段落中的此链接:msdn.microsoft.com/de-de/library/dd547125.aspx。它在 F# 而不是 C# 中,但我想这就是你想要实现的。如果您想发布一些与 F# 代码相同的 C# 代码。

标签: c# inheritance dynamic methods parameters


【解决方案1】:

您不应该违反 OOP 规则。所以这是解决方案之一:

public interface IBar
{
    int Y { get; }
}

public Bar : Foo, IBar { ... }

public void foobar(IBar f) {
    int y = f.Y;
}

但如果你真的想,你可以:

使用动态:

public void foobar(Foo f) 
{
    dynamic df = (dynamic)f;
    int y;
    try
    {
       y = df.y;
    }
    catch (RuntimeBinderException)
    {
       // case when foo doesn't have a y
    }
}

或反射:

public void foobar(Foo f) 
{
    var type = f.GetType();
    var field = type.GetFields(BindigFlags.Instance 
                                | BindigFlags.Public)
                      .FirstOrDefault(info => info.Name == "y");

    if (field == null)
    {
       // case when f doesn't have a field
    }

    int y = (int)field.GetValue(f);
}

【讨论】:

  • 接口解决方案不起作用(根据我的理解),因为我可以拥有具有变量 y 的类“Foo : Bar”,然后是另一个类“Jim : Bar”有变量 q,但没有 y。每个类不会有相同的变量,它完全取决于类。我一直在寻找动态关键字。
【解决方案2】:

你试图用你的设计做什么是不可能的。想到的一种方法 - 在Foo 中定义抽象方法,所有继承的类都将覆盖此方法。此方法将返回y(或来自其他派生类的其他信息)。

public abstract class Foo {
   public int x;
   public abstract int GetValue();
}

public class Bar : Foo 
{
  private int y;
  public Bar(int y) 
  {
    this.y = y;
  }
  public override int GetValue()
  {
     return y;
  }
}

然后你可以像这样检索值

public void foobar(Foo f) {
    int y = f.GetValue();
}

【讨论】:

    【解决方案3】:

    这可以通过duck打字来完成,请参考这个链接:Duck Typing

    这可以在 C# 中使用 dynamic 关键字来完成。

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      • 2014-06-05
      • 2019-09-25
      • 2011-12-28
      相关资源
      最近更新 更多