Feedback

C# - .NET / F# Delegaten konvertieren

Veröffentlicht von am 10/26/2014
(0 Bewertungen)
Wer C#- und F# parallel benutzt kommt vielleicht in die Situation einen Delegaten der einen Sprache in der anderen angeben oder aufrufen zu müssen.
Die Hier gezeigten Methoden konvertieren diese Delegaten zwischen einander.
Die Delegaten können maximal 4 Parameter entgegen nehmen. Die Erweiterung ist aber nicht weiter schwer.
/// <summary>
/// Stellt Methoden zum Konvertieren von C#- und F#-Delegaten bereit.
/// </summary>
public class FSFunc
{
    /// <summary>
    /// Konvertiert einen C#-Delegaten mit einem Parameter in einen F#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein C#-Delegat.</param>
    /// <returns>Ein F#-Delegat mit der selben Aufgabe wie der übergebene C#-Delegat.</returns>
    public static FSharpFunc<T1, TResult> Convert<T1, TResult>(Func<T1, TResult> func)
    {
        return new MyFSharpFunc<T1, TResult>(a => func(a));
    }
    /// <summary>
    /// Konvertiert einen C#-Delegaten mit 2 Parametern in einen F#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="T2">Der Typ des zweiten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein C#-Delegat.</param>
    /// <returns>Ein F#-Delegat mit der selben Aufgabe wie der übergebene C#-Delegat.</returns>
    public static FSharpFunc<T1, FSharpFunc<T2, TResult>> Convert<T1, T2, TResult>(Func<T1, T2, TResult> func)
    {
        return new MyFSharpFunc<T1, FSharpFunc<T2, TResult>>(a => new MyFSharpFunc<T2, TResult>(b => func(a, b)));
    }
    /// <summary>
    /// Konvertiert einen C#-Delegaten mit 3 Parametern in einen F#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="T2">Der Typ des zweiten Parameters.</typeparam>
    /// <typeparam name="T3">Der Typ des dritten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein C#-Delegat.</param>
    /// <returns>Ein F#-Delegat mit der selben Aufgabe wie der übergebene C#-Delegat.</returns>
    public static FSharpFunc<T1, FSharpFunc<T2, FSharpFunc<T3, TResult>>> Convert<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func)
    {
        return new MyFSharpFunc<T1, FSharpFunc<T2, FSharpFunc<T3, TResult>>>(a => new MyFSharpFunc<T2, FSharpFunc<T3, TResult>>(b => new MyFSharpFunc<T3, TResult>(c => func(a, b, c))));
    }
    /// <summary>
    /// Konvertiert einen C#-Delegaten mit 4 Parametern in einen F#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="T2">Der Typ des zweiten Parameters.</typeparam>
    /// <typeparam name="T3">Der Typ des dritten Parameters.</typeparam>
    /// <typeparam name="T4">Der Typ des vierten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein C#-Delegat.</param>
    /// <returns>Ein F#-Delegat mit der selben Aufgabe wie der übergebene C#-Delegat.</returns>
    public static FSharpFunc<T1, FSharpFunc<T2, FSharpFunc<T3, FSharpFunc<T4, TResult>>>> Convert<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func)
    {
        return new MyFSharpFunc<T1, FSharpFunc<T2, FSharpFunc<T3, FSharpFunc<T4, TResult>>>>(a => new MyFSharpFunc<T2, FSharpFunc<T3, FSharpFunc<T4, TResult>>>(b => new MyFSharpFunc<T3, FSharpFunc<T4, TResult>>(c => new MyFSharpFunc<T4, TResult>(d => func(a, b, c, d)))));
    }

    /// <summary>
    /// Konvertiert einen F#-Delegaten mit einem Parameter in einen C#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein F#-Delegat.</param>
    /// <returns>Ein C#-Delegat mit der selben Aufgabe wie der übergebene C#-Delagat.</returns>
    public static Func<T1, TResult> Convert<T1, TResult>(FSharpFunc<T1, TResult> func)
    {
        return (a) => func.Invoke(a);
    }
    /// <summary>
    /// Konvertiert einen F#-Delegaten mit 2 Parametern in einen C#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="T2">Der Typ des zweiten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein F#-Delegat.</param>
    /// <returns>Ein C#-Delegat mit der selben Aufgabe wie der übergebene C#-Delagat.</returns>
    public static Func<T1, T2, TResult> Convert<T1, T2, TResult>(FSharpFunc<T1, FSharpFunc<T2, TResult>> func)
    {
        return (a, b) => func.Invoke(a).Invoke(b);
    }
    /// <summary>
    /// Konvertiert einen F#-Delegaten mit 3 Parametern in einen C#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="T2">Der Typ des zweiten Parameters.</typeparam>
    /// <typeparam name="T3">Der Typ des dritten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein F#-Delegat.</param>
    /// <returns>Ein C#-Delegat mit der selben Aufgabe wie der übergebene C#-Delagat.</returns>
    public static Func<T1, T2, T3, TResult> Convert<T1, T2, T3, TResult>(FSharpFunc<T1, FSharpFunc<T2, FSharpFunc<T3, TResult>>> func)
    {
        return (a, b, c) => func.Invoke(a).Invoke(b).Invoke(c);
    }
    /// <summary>
    /// Konvertiert einen F#-Delegaten mit 4 Parametern in einen C#-Delegaten.
    /// </summary>
    /// <typeparam name="T1">Der Typ des ersten Parameters.</typeparam>
    /// <typeparam name="T2">Der Typ des zweiten Parameters.</typeparam>
    /// <typeparam name="T3">Der Typ des dritten Parameters.</typeparam>
    /// <typeparam name="T4">Der Typ des vierten Parameters.</typeparam>
    /// <typeparam name="TResult">Der Typ des Rückgabewerts.</typeparam>
    /// <param name="func">Ein F#-Delegat.</param>
    /// <returns>Ein C#-Delegat mit der selben Aufgabe wie der übergebene C#-Delagat.</returns>
    public static Func<T1, T2, T3, T4, TResult> Convert<T1, T2, T3, T4, TResult>(FSharpFunc<T1, FSharpFunc<T2, FSharpFunc<T3, FSharpFunc<T4, TResult>>>> func)
    {
        return (a, b, c, d) => func.Invoke(a).Invoke(b).Invoke(c).Invoke(d);
    }

    /// <summary>
    /// Hilfsklasse um die abstrakte <see cref="Microsoft.FSharp.Cor.FSharpFunc{T,TResult}"/>-Klasse verwenden zu können.
    /// </summary>
    private class MyFSharpFunc<T1, TResult> : FSharpFunc<T1, TResult>
    {
        internal MyFSharpFunc(Func<T1, TResult> func)
        {
            this.func = func;
        }

        public override TResult Invoke(T1 func)
        {
            return this.func(func);
        }

        Func<T1, TResult> func;

        public static implicit operator MyFSharpFunc<T1, TResult>(Func<T1, TResult> func)
        {
            return new MyFSharpFunc<T1, TResult>(func);
        }
    }
}
Abgelegt unter F#, Delegate, .NET, Generics.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!