2

I currently have a PCL library that incorporates a factory something like this (names changed to protect the innocent):

public abstract class ThingFactory : IThingFactory
{
    private readonly Dictionary<string, Func<object>> _registrations = new Dictionary<string, Func<object>>();

    protected void Register<T>(string name, Func<IThing<T>> resolver) where T : IModel<T>
    {
        _registrations.Add(name, resolver);
    }

    // ... Resolve casts invocation back to IThing<T>.
}

The library builds and tests perfectly for .NET 4.0 above and SL 5.

Any other targets (SL 4, Windows phone etc) cause a compilation failure with the conversion message:

Error 2 Argument 2: cannot convert from 'System.Func<IThing<T>>' to 'System.Func<object>'

Any suggestions?


Yes, it's in the Text.Printf module, and it's just called printf.

> import Text.Printf
> let x = 1.14907259
> putStrLn . printf "%.2f" $ x
1.15

Note that the return type of printf is overloaded, so that it's capable of returning a String (as in the example above) but it's also capable of returning an I/O action that does the printing, so you don't actually need the call to putStrLn:

> printf "%.2f\n" x
1.15
4

2 に答える 2

5

これFunc<T>は、.NET 3.5 でこのように宣言されたためです。

public delegate TResult Func<TResult>()

.NET4 以降、宣言は次のように変更されました。

public delegate TResult Func<out TResult>()

out.NET 3.5 宣言にキーワードがないことに注意してください。ジェネリック型を共変にします。MSDN で .NETの共分散と反分散のサポートに関する非常に優れた説明を読むことができます。

于 2013-03-22T09:15:44.297 に答える
2

次のコードを使用して修正できます。

    protected void Register<T>(string name, Func<IThing<T>> resolver) where T : IModel<T>
    {
        Func<object> wrapper =  () => resolver();
        _registrations.Add(name, wrapper);
    }

その理由は、.NET 4.0 より前には func/action のバリアンス サポートがないためだと思います。

于 2013-03-22T09:08:54.347 に答える