我有一个场景,我希望能够通过一个方法参数传递一个类,并从传递的类的实例中获取特定于类的信息。
示例:
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。
我需要能够在没有典型代码的情况下完成此操作,以便动态处理该类。
我知道我可以说
((Bar)f).y
然而,重点是我会传递多个类,静态类型转换会破坏目的。
答案 0 :(得分: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);
}
答案 1 :(得分:0)
这可以通过鸭子打字来完成,请参阅此链接:Duck Typing。
这可以通过使用动态关键字在C#中完成。
答案 2 :(得分: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();
}