有什么方法可以从代码本身获取 属性 的定义?
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:构造对象实例并读取 属性。
无论如何,这里有一些选择,有创意的头脑可能会找到更多。
构造实例,读取属性.
这是代码方面的最佳选择,因为它易于理解、维护和修复错误。
重写代码以允许使用反射轻松检测值
一种方法是使用属性,用合法移动标记 属性 或对象。 但是,为了避免属性做一件事,代码做另一件事的错误,您可能必须更改代码以同时使用属性,这会影响性能。
此外,读取这些属性可能会构造比原始对象更多的对象。
使用 mono.cecil 或其他一些 IL 检查库来解码 属性 getter 的代码并找到该列表的构造,提取值被添加到列表中。您基本上要么必须简化 属性 的代码以与您现在拥有的代码相提并论(永远不要让它变得更复杂),要么基本上模拟代码的执行。
这就像建造一支 space 舰队,火力足以摧毁一个当地的星系,只是为了杀死一只蚂蚁。
底线,构造对象实例,读取属性.
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:构造对象实例并读取 属性。
无论如何,这里有一些选择,有创意的头脑可能会找到更多。
构造实例,读取属性.
这是代码方面的最佳选择,因为它易于理解、维护和修复错误。
重写代码以允许使用反射轻松检测值
一种方法是使用属性,用合法移动标记 属性 或对象。 但是,为了避免属性做一件事,代码做另一件事的错误,您可能必须更改代码以同时使用属性,这会影响性能。
此外,读取这些属性可能会构造比原始对象更多的对象。
使用 mono.cecil 或其他一些 IL 检查库来解码 属性 getter 的代码并找到该列表的构造,提取值被添加到列表中。您基本上要么必须简化 属性 的代码以与您现在拥有的代码相提并论(永远不要让它变得更复杂),要么基本上模拟代码的执行。
这就像建造一支 space 舰队,火力足以摧毁一个当地的星系,只是为了杀死一只蚂蚁。
底线,构造对象实例,读取属性.