2014-05-03 1 views
0

La source suivante fonctionne comme prévu lorsque vous utilisez .NET dans Visual Studio, mais il jette l'exception mentionnée ci-dessus lors de l'utilisation du cadre Mono:ArgumentException: type de retour de la méthode est incompatible (Mono)

class Foo<TEnum> where TEnum : struct { 

    private static Func<int, int> Identity = (value) => value; 
    private static Func<int, TEnum> IntToEnum = Delegate.CreateDelegate(typeof(Func<int, TEnum>), Identity.Method) as Func<int, TEnum>; 
    private static Func<TEnum, int> EnumToInt = Delegate.CreateDelegate(typeof(Func<TEnum, int>), Identity.Method) as Func<TEnum, int>; 

    public static bool EnumEquals(TEnum lhs, TEnum rhs) { 
     return EnumToInt(lhs) == EnumToInt(rhs); 
    } 

} 

Foo<SomeEnum>.EnumEquals(SomeEnum.A, SomeEnum.B); 

Y at-il une solution de contournement à ce qui, comme ci-dessus, évite les valeurs de boxe/unboxing?

Je suis coincé avec la mise en œuvre Mono qui se trouve à l'intérieur de l'unité:/

L'exception

ArgumentException: method return type is incompatible 
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Delegate.cs:190) 
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Delegate.cs:291) 
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Delegate.cs:295) 
Foo`1[SomeEnum]..cctor() 
... 
+0

Je ne suis pas certain de la fiabilité de cette proposition, mais elle semble fonctionner (http://hastebin.com/ahoxoleyed.cs). –

Répondre

1

Eh bien, je ne comprends pas tout à fait ce qui suit, mais il semble travailler pour à la fois .NET et Mono et il n'alloue pas. Tout commentaire sur les réserves ou la fiabilité serait apprécié!

Cela a été adapté from here (la seule différence est que Expression.Parameter nécessite un second paramètre pour plaire à la version de Mono qui est utilisé par l'unité

internal static class CastTo<T> { 
    public static T From<S>(S s) { 
     return Cache<S>.caster(s); 
    } 

    static class Cache<S> { 
     internal static readonly Func<S, T> caster = Get(); 

     static Func<S, T> Get() { 
      var p = Expression.Parameter(typeof(S), "S"); 
      var c = Expression.ConvertChecked(p, typeof(T)); 
      return Expression.Lambda<Func<S, T>>(c, p).Compile(); 
     } 
    } 
} 

qui peut alors être utilisé comme suit:.

public enum Example { 
    A, 
    B, 
    C, 
} 

long example = CastTo<long>.From<Example>(Example.B); 
Questions connexes