Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.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# - Fatal编程技术网

C# 检查表达式是否包含特定属性

C# 检查表达式是否包含特定属性,c#,C#,给定一个签名如下的方法: MyMethod(params Expression<Func<Subscription, object>>[] fields) 如何检查传递给MyMethod的表达式?例如: MyMethod(Expression<Func<Subscription, object>>[] fields) { //using contains like this doesnt seem to work if(field

给定一个签名如下的方法:

MyMethod(params Expression<Func<Subscription, object>>[] fields)
如何检查传递给
MyMethod
的表达式?例如:

MyMethod(Expression<Func<Subscription, object>>[] fields) {
    //using contains like this doesnt seem to work
    if(fields.Contains(x=> x.SomeProperty)) {...}
}
MyMethod(表达式[]字段){
//像这样使用contains似乎不起作用
如果(fields.Contains(x=>x.SomeProperty)){…}
}

表达式非常通用。您可能首先需要过滤
MemberExpression
中的字段:

public static void MyMethod(params Expression<Func<Subscription, object>>[] fields)
{
    var memberExpressions = fields
        .Where(f => typeof(MemberExpression).IsAssignableFrom(f.Body.GetType()))
        .Select(f => (MemberExpression)f.Body)
        .ToList();
    if (memberExpressions.Any(ex => 
        ex.Member.MemberType == MemberTypes.Property &&
        ex.Member.Name == "SomeProperty"))
    {
        Console.WriteLine("At least one of the fields expressions passed to this function were x => x.SomeProperty");
    }
}
公共静态void MyMethod(参数表达式[]字段)
{
var memberExpressions=字段
.Where(f=>typeof(MemberExpression).IsAssignableFrom(f.Body.GetType())
.选择(f=>(MemberExpression)f.Body)
.ToList();
if(memberExpressions.Any)(ex=>
ex.Member.MemberType==MemberTypes.Property&&
ex.Member.Name==“SomeProperty”))
{
WriteLine(“传递到此函数的至少一个字段表达式为x=>x.SomeProperty”);
}
}

表达式非常通用。您可能首先需要过滤
MemberExpression
中的字段:

public static void MyMethod(params Expression<Func<Subscription, object>>[] fields)
{
    var memberExpressions = fields
        .Where(f => typeof(MemberExpression).IsAssignableFrom(f.Body.GetType()))
        .Select(f => (MemberExpression)f.Body)
        .ToList();
    if (memberExpressions.Any(ex => 
        ex.Member.MemberType == MemberTypes.Property &&
        ex.Member.Name == "SomeProperty"))
    {
        Console.WriteLine("At least one of the fields expressions passed to this function were x => x.SomeProperty");
    }
}
公共静态void MyMethod(参数表达式[]字段)
{
var memberExpressions=字段
.Where(f=>typeof(MemberExpression).IsAssignableFrom(f.Body.GetType())
.选择(f=>(MemberExpression)f.Body)
.ToList();
if(memberExpressions.Any)(ex=>
ex.Member.MemberType==MemberTypes.Property&&
ex.Member.Name==“SomeProperty”))
{
WriteLine(“传递到此函数的至少一个字段表达式为x=>x.SomeProperty”);
}
}
您可以实现,并在表达式树中查找名为
SomeProperty
的属性:

internal class Finder : ExpressionVisitor {
    private readonly string toFind;
    public Finder(string toFind) {
        this.toFind = toFind;
    }
    public bool IsFound { get; private set; }
    protected override Expression VisitMember(MemberExpression node) {
        IsFound |= node.Member.MemberType == MemberTypes.Property && node.Member.Name == toFind;
        return base.VisitMember(node);
    }
}
按如下方式使用访客:

static void MyMethod(params Expression<Func<Program,object>>[] fields) {
    foreach (var fieldExpr in fields) {
        var finder = new Finder("Foo");
        finder.Visit(fieldExpr);
        if (finder.IsFound) {
            Console.WriteLine("Expression {0} references 'Foo'", fieldExpr);
        } else {
            Console.WriteLine("Expression {0} does not reference 'Foo'", fieldExpr);
        }
    }
}
生成此输出:

Expression e => e.Foo references 'Foo'
Expression e => e.Bar does not reference 'Foo'
Expression e => IIF((e.Bar != null), e.Foo, e.Bar) references 'Foo'

您可以实现,并在表达式树中查找名为
SomeProperty
的属性:

internal class Finder : ExpressionVisitor {
    private readonly string toFind;
    public Finder(string toFind) {
        this.toFind = toFind;
    }
    public bool IsFound { get; private set; }
    protected override Expression VisitMember(MemberExpression node) {
        IsFound |= node.Member.MemberType == MemberTypes.Property && node.Member.Name == toFind;
        return base.VisitMember(node);
    }
}
按如下方式使用访客:

static void MyMethod(params Expression<Func<Program,object>>[] fields) {
    foreach (var fieldExpr in fields) {
        var finder = new Finder("Foo");
        finder.Visit(fieldExpr);
        if (finder.IsFound) {
            Console.WriteLine("Expression {0} references 'Foo'", fieldExpr);
        } else {
            Console.WriteLine("Expression {0} does not reference 'Foo'", fieldExpr);
        }
    }
}
生成此输出:

Expression e => e.Foo references 'Foo'
Expression e => e.Bar does not reference 'Foo'
Expression e => IIF((e.Bar != null), e.Foo, e.Bar) references 'Foo'

你的问题建立在错误的假设之上。
表达式
不一定只是一个属性访问操作,它可以是一个文本值或另一种类型的表达式,例如
MyMethod(x=>5+2)
MyMethod(x=>null)
,或者作为另一个表达式的一部分以名称传入的内容:
MyMethod(x=>this.SomeDelegate(x).SomeExtensionMethod()??123)
@Dai谢谢。为了实现与我的示例类似的方法,您是否建议使用不同的参数签名?注意:对于这个用例,不需要担心人们做
x=>5+2
。最终目标只是让用户能够轻松地指定要以强类型方式指定的对象属性。您的问题是建立在错误的假设基础上的。
表达式
不一定只是一个属性访问操作,它可以是一个文本值或另一种类型的表达式,例如
MyMethod(x=>5+2)
MyMethod(x=>null)
,或者作为另一个表达式的一部分以名称传入的内容:
MyMethod(x=>this.SomeDelegate(x).SomeExtensionMethod()??123)
@Dai谢谢。为了实现与我的示例类似的方法,您是否建议使用不同的参数签名?注意:对于这个用例,不需要担心人们做
x=>5+2
。最终目标只是让用户能够轻松地指定要以强类型方式指定的对象属性。