2011-06-13 122 views
0

我有一个对象“ConnectableProperty”,将一个属性挂钩到另一个属性,并要求我给它提供Func。现在我有2种类型 - 标量和颜色。两者都可以通过明确的操作符相互转换。由于某些原因,我无法提供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; 
    } 
} 

而且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

你能举个例子吗?你现在怎么做? – 2011-06-13 12:13:20

+0

你可以发布你的对象?如果只能明确表演,那么我不会看到Func如何工作。 – IndigoDelta 2011-06-13 12:13:45

+0

也许如果有某种类型的继承,或者接口实现可以将标量func提供给颜色1,但不是这样的 – Atzoya 2011-06-13 12:16:21

回答

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,他们也需要将结果转换为X

+0

能否声明自己的'Func'类型并指定第三个参数是'out'(协方差)。这会起作用吗? – 2011-06-13 12:16:12

+0

@zespri:'Func '的结果参数在.NET 4中已经是协变的,但协方差不适用于用户定义的转换。 – 2011-06-13 12:20:24

+0

总是有意义的。谢谢。 – 2011-06-13 12:26:24

0

不会简单地在函数体内使用显式强制转换吗?那么你可以只使用一种类型的功能 - 不需要铸造

6

Jon是对的;只是为了补充一点:

首先,这是行不通的原因是因为没有地方的转换存在。假设您有:

Func<int> f1 =()=>1; 
Func<double> f2 = f1; 

假设这是合法的。某处,C#编译器必须生成将int转换为double的指令。哪里?不在lambda中;那东西必须在调用f1时返回一个int。但是也不是在f2中,因为f1是参考相同的到f1。有两种可能的解决方案:使其成为非法,或使其实际意思是:

f2 =()=>(double)f1(); 

使得f1和f2不再相同。我们选择了第一个解决方案。

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