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

Any way to get the definition of a property from the code itself?

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()

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

但是我怎样才能检索到允许移动的列表?

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

无论如何,这里有一些选择,有创意的头脑可能会找到更多。

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

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

  2. 重写代码以允许使用反射轻松检测值

    一种方法是使用属性,用合法移动标记 属性 或对象。 但是,为了避免属性做一件事,代码做另一件事的错误,您可能必须更改代码以同时使用属性,这会影响性能。

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

  3. 使用 mono.cecil 或其他一些 IL 检查库来解码 属性 getter 的代码并找到该列表的构造,提取值被添加到列表中。您基本上要么必须简化 属性 的代码以与您现在拥有的代码相提并论(永远不要让它变得更复杂),要么基本上模拟代码的执行。

    这就像建造一支 space 舰队,火力足以摧毁一个当地的星系,只是为了杀死一只蚂蚁。

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