C#-通过参数传递继承的类

C#-通过参数传递继承的类,c#,inheritance,dynamic,methods,parameters,C#,Inheritance,Dynamic,Methods,Parameters,我有一个场景,在这个场景中,我希望能够通过methods参数传递一个类,并从传递的类的实例中获取特定于类的信息 例如: public abstract class Foo { public int x; } 然后 我需要做的是这样的事情 public void foobar(Foo f) { int y = f.y; } public void foobar(Foo f) { int y = f.GetValue(); } 可以这样称呼: foobar(new Bar

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

例如:

public abstract class Foo {
   public int x;
}
然后

我需要做的是这样的事情

public void foobar(Foo f) {
    int y = f.y;
}
public void foobar(Foo f) {
    int y = f.GetValue();
}
可以这样称呼:

foobar(new Bar(5));
这将获得一个特定于类“Bar”的值,该类从类Foo“继承”

我需要能够在没有类型转换的情况下完成这项工作,以便动态处理该类

我知道我只能说

((Bar)f).y

然而,关键是我将有多个类被传递,静态类型转换将无法达到目的

这可以通过duck键入来完成,请参考此链接:


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

这可以通过duck键入来完成,请参阅此链接:


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

您试图对设计执行的操作是不可能的。想到的一种方法是在
Foo
中定义抽象方法,所有继承的类都将重写此方法。此方法将返回
y
(或来自其他派生类的其他信息)

然后您可以像这样检索值

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

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

然后您可以像这样检索值

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

你不应该违反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);
}

你不应该违反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);
}

那么为什么不在Foo中定义y呢?特别是如果你想在任何继承的类中得到y值,但是它会打败面向对象编程。你不能准备界面,f.e IBar和
y
属性吗?看看MSDN中“标识符模式”一段的链接:。这是F#而不是C#但我想这是你想要实现的。如果你想要a,你可以发布一些C代码,实现与F代码相同的功能。那么为什么不在Foo中定义y呢?特别是如果你想在任何继承的类中得到y值,但是它会打败面向对象编程。你不能准备界面,f.e IBar和
y
属性吗?看看MSDN中“标识符模式”一段的链接:。这是F#而不是C#但我想这是你想要实现的。如果你想要a,你可以发布一些C代码,实现与F代码相同的功能。接口解决方案不起作用(从我的理解来看),因为我可能有一个类“Foo:Bar”包含变量y,然后另一个类“Jim:Bar”包含变量q,但不是y。每个类不会有相同的变量,它完全取决于类。动态关键字就是我要找的。接口解决方案不起作用(从我的理解来看),因为我可能有一个类“Foo:Bar”包含变量y,然后另一个类“Jim:Bar”包含变量q,但不是y。每个类不会有相同的变量,它完全取决于类。动态关键字就是我要找的。