נניח שיש לנו Property שאנחנו ניגשים אליו הרבה פעמים בReflection.
הפעולה הזו די יקרה ויכולה להאט משמעותית את התכנית שלנו.
אחת הדרכים שנראה שאפשר לעשות כדי לפתור בעיה זו היא להשתמש בDelegate.CreateDelegate, אלא שיש פה בעיה:
אם הפרמטרים שלנו הם לא מהטיפוס המתאים, לא נוכל ליצור Delegate כזה.
לדוגמה, נניח שיש לנו את הProperty הבא:
1
2
3
4
5
6
7
8
public  class  Triangle  : Shape 
{
    public  Circle BoundedCircle
    {
        get ;
        set ;
    }
}
אז הקריאה הבאה תעבוד:
1
2
3
4
5
6
7
8
9
10
11
12
13
PropertyInfo boundedCircleProperty =
    typeof (Triangle).GetProperty("BoundedCircle" );
Func<Triangle, Circle> getBoundedCircle =
    (Func<Triangle, Circle>)
    Delegate.CreateDelegate(typeof (Func<Triangle, Circle>),
                            boundedCircleProperty.GetGetMethod());
Triangle myTriangle = new  Triangle();
object  boundedCircle =
    getBoundedCircle(myTriangle);
אבל מה הבעיה? הבעיה היא שאנחנו לא מכירים את הטיפוס Triangle. זהו טיפוס שהתקבל בReflection. אם היינו מכירים אותו, היינו לעשות הסבה ולגשת לProperty ששמו BoundedCircle בעצמנו במהירות סבירה.
אם ננסה לעשות משהו כזה, נחטוף כמובן Exception:
1
2
3
4
Func<Shape, Circle> getBoundedCircle =
    (Func<Shape, Circle>)
    Delegate.CreateDelegate(typeof (Func<Shape, Circle>),
                            boundedCircleProperty.GetGetMethod());
כי הפונקציה מצפה לקבל Triangle ולא Shape.
מה שנוכל לעשות זה ליצור מתודה דינאמית בזמן ריצה שתעשה את זה:
הגישה הזאת תראה ככה:
1
2
Expression<Func<Shape, Circle>> boundedCircleExpression =
    x => ((Triangle) x).BoundedCircle;
מה שמתמקפל למשהו כזה:
1
2
3
4
5
6
7
8
9
10
11
ParameterExpression parameter =
Expression.Parameter(typeof (Shape), "x" );
PropertyInfo boundedCircleProperty =
    typeof (Triangle).GetProperty("BoundedCircle" );
Expression<Func<Shape, Circle>> boundedCircleExpression =
    Expression.Lambda<Func<Shape, Circle>>
        (Expression.Property
             (Expression.Convert(parameterX, typeof (Triangle)), boundedCircleProperty),
         new  ParameterExpression[] { parameterX });
נוכל ליצור פונקציה שיוצרת ככה Delegate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public  static  Func<TSource, TResult> GetProperty<TSource, TResult>(PropertyInfo property)
{
    ParameterExpression parameterX = Expression.Parameter(typeof (TSource), "x" );
    Expression<Func<TSource, TResult>> propertyAccessExpression =
        Expression.Lambda<Func<TSource, TResult>>
            (Expression.Property
                 (Expression.Convert(parameterX, property.ReflectedType), property),
             new  ParameterExpression[] { parameterX });
    Func<TSource, TResult> propertyAccess = propertyAccessExpression.Compile();
    return  propertyAccess;
}
ולהשתמש בו:
1
2
3
4
5
6
7
8
9
PropertyInfo boundedCircleProperty =
    typeof (Triangle).GetProperty("BoundedCircle" );
Shape myTriangle = new  Triangle();
Func<Shape, Shape> boundedCircleAccess =
    GetProperty<Shape, Shape>(boundedCircleProperty);
Shape boundedCircle = boundedCircleAccess(myTriangle);
במהירות סבירה.
נוכל לעשות גם הסבה נוספת בפונקציה במקרה הצורך (למשל במקרה של boxing לobject) בצורה הזאת:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  static  Func<TSource, TResult> GetProperty<TSource, TResult>(PropertyInfo property)
{
    ParameterExpression parameterX = Expression.Parameter(typeof (TSource), "x" );
    Expression<Func<TSource, TResult>> propertyAccessExpression =
        Expression.Lambda<Func<TSource, TResult>>
            (Expression.Convert
                 (Expression.Property
                      (Expression.Convert(parameterX, property.ReflectedType),
                       property),
                  typeof  (TResult)),
             new  ParameterExpression[] {parameterX});
    Func<TSource, TResult> propertyAccess = propertyAccessExpression.Compile();
    return  propertyAccess;
}
סופ"ש דינאמי מצוין