Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “获取完整类属性”;“树”;名称为字符串_C#_.net_Properties_Linq Expressions - Fatal编程技术网

C# “获取完整类属性”;“树”;名称为字符串

C# “获取完整类属性”;“树”;名称为字符串,c#,.net,properties,linq-expressions,C#,.net,Properties,Linq Expressions,我想做的可能有点奇怪。 但是我试图(这是我能解释的最好的方法)使用反射来获取一个完整的类属性树名称作为字符串 迄今为止的成功范例: 通过使用表达式,我能够转换: () => Model.Cargo.Id 插入字符串: "Model.Cargo.Id" "IsSet" 我现在的问题是当我在混音中使用数组时,我没有得到数组名称。我只知道最后一个名字 失败示例: Model.CargoTasks[j].IsSet 仅返回字符串: "Model.Cargo.Id" "IsSet"

我想做的可能有点奇怪。 但是我试图(这是我能解释的最好的方法)使用反射来获取一个完整的类属性树名称作为字符串


迄今为止的成功范例

通过使用表达式,我能够转换:

() => Model.Cargo.Id
插入字符串:

"Model.Cargo.Id"
"IsSet"

我现在的问题是当我在混音中使用数组时,我没有得到数组名称。我只知道最后一个名字

失败示例

Model.CargoTasks[j].IsSet
仅返回字符串:

"Model.Cargo.Id"
"IsSet"
理想情况下我想要以下字符串结果:

"Model.CargoTasks[0].IsSet"
我可能会要求在结果中包含索引,但如果这是可能的话,那将是幻想


我用来处理这些示例的代码如下所示:

public static string ToMemberAccess<TResult>(this Expression<Func<TResult>> expression)
{
    // Get the body of the expression
    Expression body = expression.Body;
    if (body.NodeType != ExpressionType.MemberAccess && body.NodeType != ExpressionType.Convert)
    {
        throw new ArgumentException("Property expression must be of the form '() => SomeProperty'", "expression");
    }

    var memberExpression = expression.Body as MemberExpression ?? ((UnaryExpression)expression.Body).Operand as MemberExpression;
    var stuff = GetMemberNames(memberExpression);
    stuff.Reverse();

    return string.Join(".", stuff);
}

static List<string> GetMemberNames(MemberExpression expression,  List<string> actual = null)
{
    if (actual == null) actual = new List<string>();

    var member = expression.Member;
    var subExp = expression.Expression as MemberExpression;
    actual.Add(member.Name);

    if(subExp != null) actual = GetMemberNames(subExp, actual);

    return actual;
}
公共静态字符串tomberaccess(此表达式)
{
//获取表达式的主体
expressionbody=Expression.body;
if(body.NodeType!=ExpressionType.MemberAccess&&body.NodeType!=ExpressionType.Convert)
{
抛出新ArgumentException(“属性表达式的形式必须为“()=>SomeProperty””,“表达式”);
}
var memberExpression=expression.Body作为memberExpression???((UnaryExpression)expression.Body)。操作数作为memberExpression;
var stuff=GetMemberNames(memberExpression);
stuff.Reverse();
返回字符串。Join(“.”,stuff);
}
静态列表GetMemberName(MemberExpression表达式,List actual=null)
{
如果(实际值==null)实际值=新列表();
var member=expression.member;
var subExp=expression.expression作为MemberExpression;
实际添加(成员名称);
if(subExp!=null)actual=GetMemberNames(subExp,actual);
返回实际值;
}

提前谢谢您!任何帮助都将不胜感激

要在索引器中获取值,必须编译并执行表达式-这是非常昂贵的,但是可以使用修改后的
ExpressionStringBuilder来完成。注意,我添加了一个参数,
compileConstants
。当设置为
false
时,输出类似于
Model.CargoTasks[\uj.j].IsSet

请注意,此示例访问者不完整(即,它不支持所有类型的表达式)。您可以使用

公共静态字符串ToMemberAccess(表达式,bool compileConstants=false)
{
var builder=新表达式字符串builder(compileConstants);
参观(表达);
返回builder.ToString();
}
内部类ExpressionStringBuilder:ExpressionVisitor
{
私有只读bool_compileConstants;
私有只读StringBuilder\u out;
公共表达式字符串生成器(bool compileConstants)
{
_compileConstants=compileConstants;
_out=新的StringBuilder();
}
受保护的重写表达式VisitConstant(ConstantExpression节点)
{
if(node.Value!=null)
{
string text=node.Value.ToString();
if(node.Value为字符串)
{
Out(“\”);
输出(文本);
Out(“\”);
}
else if(text==node.Value.GetType().ToString())
{
出(出);
}
其他的
{
输出(文本);
}
}
其他的
{
输出(“空”);
}
返回节点;
}
受保护的重写表达式VisitMethodCall(MethodCallExpression节点)
{
int num=0;
表达式=node.Object;
if(Attribute.GetCustomAttribute(node.Method,typeof(ExtensionAttribute))!=null)
{
num=1;
表达式=节点。参数[0];
}
var name=node.Method.name;
变量isIndexer=name==“获取项目”;
if(表达式!=null)
{
参观(表达);
如果(!isIndexer)
{
出('.');
}
}
if(isIndexer)
Out(“[”);
其他的
{
(姓名);
""("""),;
}
int i=num;
int count=node.Arguments.count;
而(我<计数)
{
如果(i>num)
{
外(“,”);
}
VisitArgument(node.Arguments[i]);
i++;
}
输出(isIndexer?']':');
返回节点;
}
受保护的重写表达式VisitIndex(IndexExpression节点)
{
如果(node.Object!=null)
{
访问(node.Object);
}
其他的
{
Out(node.Indexer.DeclaringType.Name);
}
if(node.Indexer!=null)
{
外(“.”);
Out(node.Indexer.Name);
}
Out(“[”);
对于(var index=0;index0)
{
外(“,”);
}
变量表达式=节点.参数[索引];
视觉目标(表达);
}
外(']');
返回节点;
}
受保护的重写表达式VisitLambda(表达式节点)
{
访问(节点、主体);
返回节点;
}
受保护的重写表达式VisitMember(MemberExpression节点)
{
OutMember(node.Expression,node.Member);
返回节点;
}
公共重写字符串ToString()
{
返回_out.ToString();
}
私有void VisitArgument(表达式)
{
如果(_compileConstants)
{
//TODO:可能检查表达式是否不依赖于参数
var value=Expression.Lambda(Expression.Compile().DynamicInvoke();
输出(值+字符串.空);
}
其他的
{
VisitAr