我有一个对象“ConnectableProperty”,它将一个属性连接到另一个属性,并且需要我提供它Func。现在我有2种类型 - Scalar和Color。两者都可以通过显式运算符相互转换。出于某种原因,我无法将Func<double, double, Scalar>
提供给Func<double, double Color>
,即使Scalar可以转换为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;
}
}
和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;
}
}
答案 0 :(得分:6)
首先,这不起作用的原因是因为没有转换存在的地方。假设你有:
Func<int> f1 = ()=>1;
Func<double> f2 = f1;
假设这是合法的。某处,C#编译器必须生成一个指令,它将int转换为double。哪里?不在lambda;调用f1时,该东西必须返回一个int。但也不是在f2中,因为f1与引用相同到f1。有两种可能的解决方案:将其设为非法,或者使其真正意味着:
f2 = ()=>(double)f1();
使f1和f2不再相同。我们选择了第一个解决方案。
其次,如果返回类型之间存在隐式的引用转换,那么这在C#4中是合法的。我们不需要发出任何隐式引用转换的指令;它是合法的,没有任何特殊代码。
答案 1 :(得分: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);
}
如果您有一个要返回特定类型的委托,则必须能够直接调用 并返回相应类型的值。调用者不应该知道即使他们有Func<X>
,如果他们想要获得X
,他们也需要将结果转换为{{1} }}
答案 2 :(得分:0)
只是在函数体内部使用显式强制转换才能完成这项工作?那么你只能使用一种类型的函数 - 不需要强制转换