所以我写了这段代码,它可以从start
对象解析属性路径,返回想要的属性,并为source
可以调用返回属性的对象获取一个 out 参数:
public static PropertyInfo GetProperty(string path, object start, out object source)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentException();
source = start;
var pType = source.GetType();
var paths = path.Split('.');
PropertyInfo pInfo = null;
for (int i = 0; i < paths.Length; i++) {
var subpath = paths[i];
pInfo = pType.GetProperty(subpath);
if (i < paths.Length - 1) { // wonder if there's a better way writing this to avoid this if?
source = pInfo.GetValue(source);
pType = source.GetType();
}
}
return pInfo;
}
现在假设我有以下层次结构:
public class Object
{
public string Name { get; set; }
}
public class GameObject : Object { }
public class Component : Object
{
public GameObject gameObject { get; set; }
}
public class MonoBehaviour : Component { }
public class Player : MonoBehaviour { }
public class GameManager : MonoBehaviour
{
public Player player { get; set; }
}
示例用法:
var game = new GameManager
{
player = new Player { gameObject = new GameObject { Name = "Stu"} }
};
// somewhere else...
object source;
var name = GetProperty("player.gameObject.Name", game, out source);
var value = name.GetValue(source); // returns "Stu"
我的问题是:这显然只适用于属性,我怎样才能让它同时适用于属性和字段?- 事情是,在 andMemberInfo
之间很常见FieldInfo
,PropertyInfo
但它没有 aGetValue
所以我不能返回 a MemberInfo
。我一直在阅读有关表达式的内容,但不确定它们在这里对我有什么帮助...
同样,我正在寻找的是(给定来源)解析以下内容的能力: X.Y.Z
其中 X、Y、Z 可以是属性或字段。
编辑:
所以我稍微修改了代码来做我想做的事——但这不是你所说的干净整洁的代码,太多的输出参数:
public static bool TryParse(string path, object start, out PropertyInfo pinfo, out FieldInfo finfo, out object source)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentException();
var type = start.GetType();
var paths = path.Split('.');
source = start;
pinfo = null;
finfo = null;
for (int i = 0; i < paths.Length; i++) {
var subpath = paths[i];
pinfo = type.GetProperty(subpath);
if (pinfo == null) {
finfo = type.GetField(subpath);
if (finfo == null)
return false;
}
if (i < paths.Length - 1) {
source = pinfo == null ? finfo.GetValue(source) : pinfo.GetValue(source);
type = source.GetType();
}
}
return true;
}
用法:
var game = new GameManager
{
player = new Player { gameObject = new GameObject { Name = "Stu" } }
};
object source;
PropertyInfo pinfo;
FieldInfo finfo;
if (TryParse("player.gameObject.Name", game, out pinfo, out finfo, out source)) {
var value = pinfo == null ? finfo.GetValue(source) : pinfo.GetValue(source);
}
它做了我想要的解析,但必须有更好的东西......