有什么方法可以从代码本身获取属性的定义吗?

时间:2018-06-02 19:50:37

标签: c# reflection properties system.type

public abstract class Unit
{
    public abstract List<Move> allowedMoves{get;}
}

public class Javelineer : Unit
{
    public List<Move> allowedMoves =>
        new List<Move> {Move.Impale, Move.JavelinThrow, Move.ShieldBlock};
}

public class Dragon : Unit
{
    public List<Move> allowedMoves =>
        new List<Move> {Move.BreatheFire, Move.Swipe, Move.Bite, Move.Devour, Move.TailBash};
}

X:

鉴于上述代码,我是否以及如何在不必实例化新对象的情况下检索给定单元的允许移动?

我知道我可以使用以下代码检索属性:

typeof(Javelineer).GetProperty("allowedMoves")

但是,如果以及如何检索此属性的定义?

Y:

客户端(网络浏览器)必须将游戏服务器发送给玩家的单位。这包括单位的类型和移动这个单位能够执行(4个可用的;类似于口袋妖怪)。

虽然在服务器上执行验证(当然),但浏览器仍然需要获取可用单元类型和允许移动的列表。

为了不重复代码,我想避免在Javascript中对这些数据进行硬编码。

阅读some excellent SO questions & answers后,我想我可以使用与此类似的代码检索所有可用单位:

Assembly.GetExecutingAssembly().GetTypes().Where(
    type => type.BaseType == typeof(Unit)
).Select(type => type.Name).ToList()

我会在服务器启动时调用此代码,缓存结果并将缓存的结果发送到每个连接的客户端,因为我觉得这段代码的调用可能很昂贵。

但是如何检索允许的移动列表?

1 个答案:

答案 0 :(得分:1)

您有几个选项,但 TL; DR :构造对象实例并阅读属性。

无论如何,这里有一些选择,创造性思维可能能够找到更多的偶数。

  1. 构造实例,读取属性。

    这是代码方面的最佳选择,因为它易于理解,维护,修复错误。

  2. 重写代码以便使用反射

    轻松检测值

    执行此操作的一种方法是使用属性,使用合法移动标记属性或对象。 然而,为避免出现属性做一件事的错误,另一个代码,你可能不得不改变代码以使用属性,这将是性能损失。

    此外,读取这些属性可能会构建比原始对象更多的对象。

  3. 使用mono.cecil或其他一些IL检查库解码属性getter的代码并查找该列表的构造,提取要添加到列表中的值。你基本上要么必须将该属性的代码愚蠢地与你现在拥有的东西相提并论(并且绝不允许它变得更复杂)或基本上模拟代码的执行。

    这就像建造一支太空战舰队,用足够的火力摧毁当地的星系,只是为了杀死一只蚂蚁。

  4. 底线,构造对象实例,读取属性。