2011-06-13 152 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中是合法的。我們不需要發佈隱式引用轉換的任何指令;沒有任何特殊的代碼是合法的。