The difference in the expression <Func <T, bool >>

Just quick and short, this time. Func<T,TResult> contravariant ( EDIT : parameter of type T is). Now I am not working with Func<T,TResult>, but rather with, Expression<Func<T,TResult>>and it seems to have reached a dead end. UPDATE - SAMPLE FULL CODE:

public interface IColoredObject
{
    string Color { get; }
}

public class Item : IColoredObject
{
    public string Color { get; set; }

    public double Price { get; set; }
}

public partial class MainWindow : Window
{
    private IList<Item> _items;

    public IList<Item> Items
    {
        get
        {
            if (_items == null)
            {
                _items = new List<Item>();
                _items.Add(new Item() { Color = "black" });
                _items.Add(new Item() { Color = "blue" });
                _items.Add(new Item() { Color = "red" });
            }
            return _items;
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        Expression<Func<IColoredObject, bool>> filter = x => x.Color == "black";
        Item i = Get(filter);
    }

    public Item Get(Expression<Func<Item, bool>> filter)
    {
        return Items.AsQueryable().Where(filter).FirstOrDefault();
    }
}

The call is made using the argument Expression<Func<IColoredObject, bool>>as an argument and should, if I did not understand the contravariance incorrectly, work because it is IColoredObjectless inferred that Item.

What I get is an exception conversion saying something like

can't convert

System.Linq.Expressions.Expression`1[System.Func`2[MyNs.IColoredObject,System.Boolean]]

For

System.Linq.Expressions.Expression`1[System.Func`2[MyNs.Item,System.Boolean]]

Is there a way to fix this and make it work?

EDIT:

, , . . , , MSDN Func<T, TRes>:

public Item GetFunc(Func<Item, bool> filter)
{
    return Items.AsQueryable().Where(filter).FirstOrDefault();
}

MS, , :

 Func<IColoredObject, bool> filterFunc = x => x.Color == "black";
 GetFunc(filterFunc);

, Func<T, TRes>, Expression<Func<T, TRes>>...

...

, , . , Get NHibernate . , , NHibernate , . , , , , .

+5
4

:

public Item Get(Expression<Func<Item, bool>> filter) { /* ... */  }

shoud be:

public Item Get(Expression<Func<IColoredObject, bool>> filter) { /* ... */  }

, Get, Expression<Func<IColoredObject, bool>>.

+2

Expression<TDelegate> - , . Delegate Expression<Delegate>. Item Func<IColoredObject, bool> , , Func<IColoredObject, bool> Func<Item, bool>, Expression<Func<Item, bool>> , , Item bool. , Item, , , IColoredObject.

, IColoredObject Expression<Func<IColoredObject, bool>> Item, ExpressionVisitor. , (.. ). , , , .


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

interface IGizmo
{
    bool Frobnicate();
}

class Gizmo : IGizmo
{
    public bool Frobnicate()
    {
        Console.WriteLine("Gizmo was frobnicated!");

        return true;
    }
}

public sealed class DelegateConversionVisitor : ExpressionVisitor
{
    IDictionary<ParameterExpression, ParameterExpression> parametersMap;

    public static Expression<Func<T2, TResult>> Convert<T1, T2, TResult>(Expression<Func<T1, TResult>> expr)
    {
        var parametersMap = expr.Parameters
            .Where(pe => pe.Type == typeof(T1))
            .ToDictionary(pe => pe, pe => Expression.Parameter(typeof(T2)));

        var visitor = new DelegateConversionVisitor(parametersMap);
        var newBody = visitor.Visit(expr.Body);

        var parameters = expr.Parameters.Select(visitor.MapParameter);

        return Expression.Lambda<Func<T2, TResult>>(newBody, parameters);
    }

    public DelegateConversionVisitor(IDictionary<ParameterExpression, ParameterExpression> parametersMap)
    {
        this.parametersMap = parametersMap;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        return base.VisitParameter(this.MapParameter(node));
    }

    private ParameterExpression MapParameter(ParameterExpression source)
    {
        var target = source;
        this.parametersMap.TryGetValue(source, out target);

        return target;
    }
}

class Program
{
    static void Main()
    {
        Expression<Func<IGizmo, bool>> expr = g => g.Frobnicate();

        var e2 = DelegateConversionVisitor.Convert<IGizmo, Gizmo, bool>(expr);

        var gizmo = new Gizmo();
        e2.Compile()(gizmo);
    }
}

+4

. . Get (...) Item. Item IColoredObject, IColoredObject, Item , Item. IColoredObject " ", , ( ), .

: , Item X, IColoredObject, IColoredObject X?

+1

# . , :

IEnumerable<Func<IColoredObject, bool>> ie1 = XXX;
IEnumerable<Func<Item, bool>> ie2 = ie1;                // works!

, ie2 = ie1 , . , Func<T, TResult> ( "in" ) T, IEnumerable<T> ( "out" ) T. Func<,> , IEnumerable<> .

Expression<TDelegate> - . # / .

Expression<Something> Expression<SomethingAlmostTheSame>.

+1

All Articles