Search code examples
c#resharperexpression-trees

Is it possible to statically verify structure of c# expression tree arguments?


I have a method

public static class PropertyLensMixins
{
    public static ILens<Source> PropertyLens<O,Source>
        ( this O o
        , Expression<Func<O, Source>> selector
        )
        where O: class, INotifyPropertyChanged
        where Source: class, Immutable
    {
        return new PropertyLens<O, Source>(o, selector); 
    }
}

and the idea is to use it this way

this.PropertyLens(p=>p.MyProp)

however it is an error to create a nested expression even though the compiler will accept it

this.PropertyLens(p=>p.MyProp.NestProp)

now I can catch this at runtime by parsing the expression tree. For example

var names = ReactiveUI.Reflection.ExpressionToPropertyNames(selector).ToList();
if (names.Count > 1) 
    throw new ArgumentException("Selector may only be depth 1", "selector");

I was wondering however, is there any clever way to detect this at compile time? I doubt it because the compiler is happy with the type signature but I thought I might ask anyway.

I have also tried a Resharper pattern to match it as an error

$id0$.PropertyLens($id1$=>$id1$.$id2$.$id3$)

with all placeholders being identifiers but Resharper can't seem to match it.


Solution

  • There is no way to make the compiler reject such code.

    One possible alternative would be to create a custom diagnostic using Roslyn. That way, all such errors will be marked by VS. Though it might be too much work for something like this.