简体   繁体   中英

How to Pass a Func<string, string> to a function that takes a Func<object, object>

Ok so I've got this simple class

    private class TFTheOne
    {
        private object value;

        public TFTheOne(object value)
        {
            this.value = value;
        }

        public TFTheOne Bind(Func<object, object> func)
        {
            value = func(value);
            return this;
        }

        public void PrintMe()
        {
            Console.WriteLine(value);
        }
    }

And this function

    public static string ReadFile(string filePath)
    {
        return File.ReadAllText(filePath);
    }

Now when I try to pass ReadFile to the TFTheOne.Bind function

 new TFTheOne(args[0]).Bind(ReadFile);

I get this error message

Error CS1503 Argument 1: cannot convert from 'method group' to 'Func<object, object>'

Even when I try to cast ReadFile

new TFTheOne(args[0]).Bind((Func<object, object>)ReadFile);

Is there any way around this?

You can't do that. Consider this case: your class TFTheOne holds an integer value, if you would be allowed to do that then your function would crash when you call it as it expects an string.

What you can do is to create a lambda that surrounds your Func<string, string>() and checks if the parameter passed to it is really a string:

.Bind((o) => o is string ? ReadFile((string)o) : null);

Func<T, TResult> is contravariant with respect to T , so only less specific types can be used as input.

In your case, you would need to wrap your ReadFile method to ensure it works with any object .

Something like this would work, depending on your requirements:

new TFTheOne(args[0]).Bind(o => ReadFile(o?.ToString()));

Although a "better" design would be to overload Bind :

public TFTheOne Bind(Func<string, object> func)
{
    value = func(value);
    return this;
}

Now because TResult is covariant , this should compile fine:

new TFTheOne(args[0]).Bind(ReadFile);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM