首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用反射获取静态属性值,派生类和基类之间的连接

使用反射获取静态属性值,派生类和基类之间的连接
EN

Stack Overflow用户
提问于 2012-05-01 20:26:19
回答 1查看 5.1K关注 0票数 3

我会尽我最大的努力在这里解释我的愿景。这是一个很烂的捏造的例子。我有几种不同类型的Bag,它们都有自己的特殊类型的Marble。每种类型的Marble都有自己的昵称集(strings)。

不幸的是,包里除了大理石之外还有其他的东西,所以仿制药在这里帮不了我。

代码语言:javascript
复制
// Bags
abstract class Bag {
    protected Type MarbleType { get; }
    protected List<Marble> _marbles;

    public void DumpBag()
    { ... }
}
class RedBag : Bag {
    override Type MarbleType { get { return typeof(RedMarble); } }
}
class BlueBag : Bag {
    override Type MarbleType { get { return typeof(BlueMarble); } }
}

// Marbles
abstract class Marble {
    public static IEnumerable<string> Nicknames {
        get {
            return new List<string>() {
               "Marble", "RollyThing"
            }
        }
    }
}
class RedMarble : Marble {
    public static IEnumerable<string> Nicknames {
        get {
            return new List<string>(Marble.Nicknames) {
                "Ruby"
            };
        }
    }
}
class BlueMarble : Marble { ... }

现在我们开始详细介绍DumpBag()的实现。考虑以下呼吁:

代码语言:javascript
复制
Bag b = new RedBag();
b.GetMarbles();
b.DumpBag();

我希望它能打印:

代码语言:javascript
复制
Bag of Marbles (aka "Marble", "RollyThing", Ruby"):
- Marble 1
- Marble 2
...

我们看到,为了打印该标题,Bag必须能够了解派生类型的Marble,而不依赖于任何实际实例。它获得了Nicknames基类的Marble连接,但也得到了派生的RedMarble

DumpBag需要执行一种“静态虚拟调用”。我已经开始用以下方法实现DumpBag

代码语言:javascript
复制
public void DumpBag() {
    PropertyInfo pi = this.MarbleType.GetProperty("Nicknames", BindingFlags.Static);
    IEnumerable<string> nicknames = pi.GetValue(null, null);  // No instance

    StringBuilder sb = new StringBuilder("Bag of Marbles (aka ");
    foreach (string nn in nicknames)
        sb.Append("\"" + nn + "\", ");
    Console.WriteLine(sb.ToString());

    ...
}

我的问题:

  1. ,这是正常的吗?希望我已经(或者可以)解释了我为什么要走这条路的理由。
  2. ,我收到了一个警告(当然),RedMarble.Nicknames隐藏了Marble.Nicknames。继续并标记它new

是否有效?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-01 20:43:16

你会发现你所缺少的只是一个明确的演员阵容:

(List<string>)this.MarbleType.GetProperty("Nicknames").GetValue(null, null);

当我测试它的时候,这对我来说很好。

正如注释中所讨论的,不应该真的使用新关键字,最好将基类静态方法命名为其他方法,这样就不会有歧义。毕竟,您控制了这一点,而不使用其他人的代码。

现在,,你应该这样做吗?

首先,您肯定希望使用泛型而不是定义的方法来返回类型:

代码语言:javascript
复制
abstract class Bag<T> where T:marble {
    public void DumpBag()
    { 
        // here you can use
        // (IEnumerable<string>)typeof(T).GetProperty("Nicknames").GetValue(null, null);
    }
}

class RedBag : Bag<RedMarble> {
}

class BlueBag : Bag<BlueMarble> {
}

当然,您可以做的第二件事是使其不是静态的,在这种情况下,属性将在Marble中进行抽象,在RedMarbleBlueMarble中被重写,然后在DumpBag中直接以Nicknames形式访问,而不是使用反射。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10403868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档