2012-03-21 12 views
5

私は三式を作成しようとしていると私は、次のエラーを取得しています三元式

「LiveSubscriptionとDisconnectedSubscriptionの間には暗黙的な変換が存在しないため、条件式のタイプを決定することができません」

同じロジックは、if文で動作しますが、私はそれが三元式では動作しません理由を理解したかった -

ここで私が何をしようとしています何の要旨です:

public interface IClientSubscription 
{ 
    bool TryDisconnect(); 
} 

public class LiveSubscription : IClientSubscription 
{ 
    public bool TryDisconnect() 
    { 
     return true; 
    } 
} 

public class DisconnectedSubscription : IClientSubscription 
{ 
    public bool TryDisconnect() 
    { 
     return true; 
    } 
} 

public class ConnectionManager 
{ 
    public readonly IClientSubscription Subscription; 

    public ConnectionManager(bool IsLive) 
    { 
     // This throws the exception 
     Subscription = (IsLive) 
      ? new LiveSubscription() 
      : new DisconnectedSubscription(); 

     // This works 
     if (IsLive) 
     { 
      Subscription = new LiveSubscription(); 
     } 
     else 
     { 
      Subscription = new DisconnectedSubscription(); 
     } 
    } 
} 

私はいつもそれをif/elseに切り替えることができましたが、まず何が間違っているのかを理解したかったのです!

答えて

8

あなたはIClientSubscriptionに、オペランドの少なくとも一つをキャストする必要があります。

Subscription = (IsLive) 
      ? (IClientSubscription)new LiveSubscription() 
      : new DisconnectedSubscription(); 

理由は三式はオペランドによって決定される特定のタイプであることです。基本的には、第2オペランドを第1オペランドの型にキャストしようとします。 LiveSubscriptionDisconnectedSubscriptionではなく、その逆もありません。
コンパイラは、両方が共通の基本型を共有しているかどうかをチェックしません。

コメントにあなたの質問に答えるためにしようと

いいえ、三項演算子は、オブジェクトのいくつかの並べ替えではありませんが、三元式が代入の右側部分です。代入の各右手部分式は特定の型を持ちます。そうでなければ、この式を左辺の変数に代入することは不可能です。
例:

  • var x = Guid.NewGuid()

    右辺式(Guid.NewGuid()Guidを返すNewGuid()方法ので、タイプGuidです。

  • var x = y.SomeMethod()

    右側の発現はSomeMethod()の戻り型の型です。

  • var x = IsLive ? "a" : 1

    これは、明らかに無効であることはないですか? xはどんなタイプですか? A またはint
    これにより、コードでのエラーメッセージとまったく同じエラーメッセージが表示されます。

  • あなたの例

    は少しは変わっ:

    var subscription = (IsLive) ? new LiveSubscription() 
              : new DisconnectedSubscription(); 
    

    注意をvarsubscription前に、私たちは今、新しい変数を初期化し、既存のではありません。私はここでも、問題が何であるかは明らかです:どのタイプがsubscriptionであるべきですか? LiveSubscriptionまたはDisconnectedSubscriptionIsLiveに応じてどちらか一方になる必要があるため、どちらにもなり得ません。 ifとの比較について

:コンパイラはSubscriptionがであることを知っているので、あなたが、IClientSubscriptionへの暗黙的なキャストが発生しているSubscriptionに新しいLiveSubscriptionインスタンスまたは新しいDisconnectedSubscriptionインスタンスを割り当て、あなたのコードで

IClientSubscriptionと入力し、LiveSubscriptionDisconnectedSubscriptionの両方を暗黙的にそのインターフェイスに変換できます。
コンパイラは最初に三項式を評価しようとしますが、それ以降はSubscriptionに割り当てようとするため、三項式の割り当ては少し異なります。これは、コンパイラが、三元式の結果がタイプIClientSubscriptionである必要があることを知らないことを意味します。

+0

「3値式が特定の型のもの」とはどういう意味ですか?同等のif/else文に対する三項表現の使用にはどのような影響がありますか?私は、三元表現が単純な構文的砂糖であるという印象を受けていましたが、それはいつかもっとですか? – William

+0

@ウィリアム:完全な答え、特にあなたが引用した文の後の段落を読んでください。私はそれがかなり明確であるという意見です。 –

+0

私は完全な答えを読んだが、私はternariesとifステートメントの使用にどのような影響があるのか​​よくわからない。すなわち、WHYは特定のタイプの三項式であるか?彼らは何らかのオブジェクトですか? – William

関連する問題