匿名方法返回类型转换

Geo*_*e R 0 c# casting anonymous-methods

我有一个对象"ConnectableProperty"将一个属性连接到另一个属性,并要求我提供它Func.现在我有2种类型 - Scalar和Color.两者都可以通过显式运算符相互转换.出于某种原因,我不能喂Func<double, double, Scalar>Func<double, double Color>,即使标量可以转换为彩色.这是怎么回事?

为了澄清,我添加了代码.请注意,可连接属性是"输入".输出(可以插入)是具有该签名的方法.

这是ConnectableProperty

public sealed class ConnectableProperty<T> : IEquatable<T>, IGetXY<T> where T : IValue<T>
{
    private T _value;
    public T Value { get { return _value; } set { _value = value; } }

    public INode ParentNode { get; private set; }
    public ValueConnection<T> Connection { get; set; }
    public INode ConnectionFrom { get { return !IsConnected ? null : Connection.FromNode; } }
    public bool IsConnected { get { return Connection == null; } }

    public ConnectableProperty(INode parentNode, T value)
    {
        ParentNode = parentNode;
        _value = value;
    }

    public T GetXY(double x, double y)
    {
        return IsConnected 
            ? Connection.FromValue(x, y) 
            : _value;
    }

    public void Connect(INode fromNode, Func<double, double, T> getXY)
    {
        Connection = new ValueConnection<T>(fromNode, ParentNode, getXY, this);
    }

    public void Disconnect()
    {
        Connection = null;
    }

    public bool Equals(T other)
    {
        return _value.Equals(other);
    }

    public static implicit operator T(ConnectableProperty<T> connectableProperty)
    {
        return connectableProperty._value;
    }
}
Run Code Online (Sandbox Code Playgroud)

和ValueConnection:

public class ValueConnection<T>
{
    public INode FromNode { get; private set; }
    public INode ToNode { get; private set; }

    public Func<double, double, T> FromValue { get; private set; }
    public ConnectableProperty<T> ToValue { get; private set; }

    public ValueConnection(INode fromNode, INode toNode, Func<double, double, T> fromValue, ConnectableProperty<T> toValue)
    {
        // TODO: Implement INPC type thing

        FromNode = fromNode;
        ToNode = toNode;

        FromValue = fromValue;
        ToValue = toValue; 
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 6

乔恩是对的; 只是为了补充:

首先,这不起作用的原因是因为没有转换存在的地方.假设你有:

Func<int> f1 = ()=>1;
Func<double> f2 = f1;
Run Code Online (Sandbox Code Playgroud)

假设这是合法的.某处,C#编译器必须生成一个将int转换为double 的指令.哪里?不在lambda; 调用f1时,该东西必须返回一个int.但不是在f2中,因为f1是 f1 相同的引用.有两种可能的解决方案:使其成为非法,或者使其真正意味着:

f2 = ()=>(double)f1();
Run Code Online (Sandbox Code Playgroud)

这样f1和f2就不再是参考相同的了.我们选择了第一个解决方案.

其次,如果返回类型之间存在隐式引用转换,则这在C#4中是合法的.我们不需要发出任何隐式引用转换的指令; 没有任何特殊代码是合法的.


Jon*_*eet 5

不,您将无法直接执行该转换,我不希望能够 - 但您可以轻松编写一对方法来执行它:

public Func<double, double, Scalar> ConvertFunc(Func<double, double, Color func)
{
    return (x, y) => (Scalar) func(x, y);
}

public Func<double, double, Color> ConvertFunc(Func<double, double, Scalar func)
{
    return (x, y) => (Color) func(x, y);
}
Run Code Online (Sandbox Code Playgroud)

如果您有一个要返回特定类型的委托,则必须能够直接调用并返回相应类型的值.调用者不应该知道即使他们有一个Func<X>,如果他们想要得到一个X,他们将需要将结果转换为X.