C# 使用反射获取静态属性值,派生类和基类的串联
我将尽我所能在这里解释我的愿景。这是一个非常蹩脚的虚构的例子。我有几种不同类型的C# 使用反射获取静态属性值,派生类和基类的串联,c#,reflection,C#,Reflection,我将尽我所能在这里解释我的愿景。这是一个非常蹩脚的虚构的例子。我有几种不同类型的包s,它们都有自己特殊类型的大理石。每种类型的Marble都有自己的昵称集(strings) 不幸的是,包里除了大理石还有其他东西,所以仿制药在这里帮不了我 // Bags abstract class Bag { protected Type MarbleType { get; } protected List<Marble> _marbles; public void Dum
包
s,它们都有自己特殊类型的大理石
。每种类型的Marble
都有自己的昵称集(string
s)
不幸的是,包里除了大理石还有其他东西,所以仿制药在这里帮不了我
// 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 { ... }
我想把它打印出来:
Bag of Marbles (aka "Marble", "RollyThing", Ruby"):
- Marble 1
- Marble 2
...
我们看到,为了打印该标题,包
必须能够了解大理石
的派生类型,而不依赖于任何实际实例。它获取大理石
基类的昵称
的串联,以及派生的红色大理石
DumpBag
需要执行一种“静态虚拟调用”。我已开始实施DumpBag
,包括以下内容:
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());
...
}
public void DumpBag(){
PropertyInfo pi=this.MarbleType.GetProperty(“昵称”,BindingFlags.Static);
IEnumerable昵称=pi.GetValue(null,null);//无实例
StringBuilder sb=新StringBuilder(“弹珠袋(aka”);
foreach(昵称中的字符串nn)
sb.附加(“\”+nn+“\”,”);
Console.WriteLine(sb.ToString());
...
}
我的问题是:
红色大理石。昵称
隐藏大理石。昵称
。继续并将其标记为新的是否有效你会发现你所缺少的只是一个明确的演员阵容:
(列表)this.MarbleType.GetProperty(“昵称”).GetValue(null,null);
当我测试它时,它对我很有效
正如在评论中所讨论的,不,你不应该使用new关键字。实际上,你最好将基类静态方法命名为其他方法,这样就不会有歧义。毕竟,你可以控制这一点,而不是使用其他人的代码
现在,你应该这样做吗 首先,您肯定希望使用泛型而不是定义的方法来返回类型:
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> {
}
抽象类包,其中T:marble{
公共垃圾袋()
{
//在这里你可以使用
//(IEnumerable)typeof(T).GetProperty(“昵称”).GetValue(null,null);
}
}
班级:红包{
}
类别:包{
}
当然,您可以做的第二件事是使它不是静态的,在这种情况下,属性将在
Marble
中抽象,并在RedMarble
和BlueMarble
中重写,然后在DumpBag
中直接作为昵称访问,而不是使用反射de>Marble.昵称
->Marble.base昵称
,您的代码示例与我的代码示例有什么不同吗?连接就像您在RedMarble.昵称
中所拥有的一样。我使用反射是因为包
本身不知道它处理的大理石
的类型,因此它使用使用虚拟属性来获取类型
,然后使用反射来获取该类型的静态属性。一定错过了代码的一部分-请注意,您有大理石。名称
不是大理石。昵称
,这让我很反感。要回答您问题的第2部分,请不要将其标记为新的,这不是真正的继承。啊,我的道歉-不是帽子应该是昵称,修正了。
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> {
}