如果委托类型是内部的,我在为F#中的属性getter编译lambda表达式时遇到一些麻烦。 这就是函数的样子:
// if I omit the 'internal' here everything works as expected module internal ReflectionHelpers = open System open System.Linq.Expressions open System.Reflection // it makes no difference if this delegate type is defined outside // of the module and marked as 'internal' type GetterFunc<'T> = delegate of 'T -> obj /// Build a getter expression function for the /// specified PropertyInfo let getGetter<'a> (p : PropertyInfo) = let inst = Expression.Parameter(p.DeclaringType, "i") let prop = Expression.Property(inst, p) let conv = Expression.Convert(prop, typeof<obj>) Expression.Lambda<GetterFunc<'a>>(conv, inst).Compile()如果我用公共类调用此方法,我会得到一个像这样的异常(仅当ReflectionHelpers模块定义为'internal'时):
System.ArgumentNullException was unhandled by user code Message=Value cannot be null. Parameter name: key Source=mscorlib ParamName=key StackTrace: at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) at System.Dynamic.Utils.CacheDict`2.TryGetValue(TKey key, TValue& value) at System.Dynamic.Utils.TypeExtensions.GetParametersCached(MethodBase method) at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters) ...可能我在这里错过了一个重点,但目前我看不出为什么会发生这种情况。
I am having some trouble with compiling a lambda expression for a property getter in F# if the delegate type is internal. This is what the function looks like:
// if I omit the 'internal' here everything works as expected module internal ReflectionHelpers = open System open System.Linq.Expressions open System.Reflection // it makes no difference if this delegate type is defined outside // of the module and marked as 'internal' type GetterFunc<'T> = delegate of 'T -> obj /// Build a getter expression function for the /// specified PropertyInfo let getGetter<'a> (p : PropertyInfo) = let inst = Expression.Parameter(p.DeclaringType, "i") let prop = Expression.Property(inst, p) let conv = Expression.Convert(prop, typeof<obj>) Expression.Lambda<GetterFunc<'a>>(conv, inst).Compile()If I call this method with a public class I get an exception like this one (only if the ReflectionHelpers module is defined as 'internal'):
System.ArgumentNullException was unhandled by user code Message=Value cannot be null. Parameter name: key Source=mscorlib ParamName=key StackTrace: at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) at System.Dynamic.Utils.CacheDict`2.TryGetValue(TKey key, TValue& value) at System.Dynamic.Utils.TypeExtensions.GetParametersCached(MethodBase method) at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters) ...Probably I am missing an important point here but currently I cannot see any reason why this is happening.
最满意答案
F#和C#使用不同的策略为委托发出Invoke方法。 如果您尝试在C#中定义类似的委托 - 委托类型将是内部但具有公共Invoke方法。 F#定义了与声明类型具有相同可见性的Invoke方法。 当Expression.Lambda中的代码尝试在给定的委托类型中查找Invoke方法时,它只查找公共方法,假设所有编译器的行为与C#类似
F# and C# use different strategies for emitting Invoke method for delegates. If you try to define similar delegate in C# it - delegate type will be internal but with public Invoke method. F# defines Invoke method with the same visibility as the declaring type. When code in Expression.Lambda tries to find Invoke method in given delegate type it looks only for public methods assuming that all compilers behave similar to C#
更多推荐
发布评论