2014-10-29 85 views
0

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

例子:

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)); 

这将得到一个特定于类“Bar”的值,该值是Foo类的“Inherits”。

我需要能够做到这一点没有typcasting,以便该类将被动态处理。

我知道,我只能说

((Bar)f).y 

然而,问题是我将不得不通过传递多个类和静态类型转换将击败目的。

+0

为什么没有定义那么在Foo中呢?特别是如果你想要在任何继承的类中获得y值。 – juharr 2014-10-29 12:28:58

+0

但它击败了面向对象的编程。你不能准备界面,f.e用'y'属性吗? – 2014-10-29 12:29:07

+0

查看MSDN的“标识符模式”的链接:http://msdn.microsoft.com/de-de/library/dd547125.aspx。它在F#中,而不是C#,但我想这就是你想要实现的。如果您希望可以发布一些与F#代码完全相同的C#代码。 – DMAN 2014-10-29 12:36:15

回答

4

你不应该打破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); 
} 
+0

接口解决方案无法工作(从我理解的方式),因为我可以让类“Foo:Bar”具有变量y,然后是另一个类“Jim:Bar”,它将具有变量q,但不会年。每个类不会有相同的变量,它完全依赖于类。动态关键字是我正在寻找的。 – Hobbyist 2014-10-29 12:58:48

0

这可以通过鸭子打字完成,请参考此链接:Duck Typing

这可以通过使用动态关键字在C#中完成。

0

你试图用你的设计做什么是不可能的。想到一种方法 - 在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(); 
}