質問

条件演算子を使用しようとしていますが、結果がどのような型であると考えられるかに悩まされています。

以下は、私が抱えている問題を示すために考案した例です。

class Program
{
    public static void OutputDateTime(DateTime? datetime)
    {
        Console.WriteLine(datetime);
    }

    public static bool IsDateTimeHappy(DateTime datetime)
    {
        if (DateTime.Compare(datetime, DateTime.Parse("1/1")) == 0)
            return true;

        return false;
    }

    static void Main(string[] args)
    {
        DateTime myDateTime = DateTime.Now;
        OutputDateTime(IsDateTimeHappy(myDateTime) ? null : myDateTime);
        Console.ReadLine();                        ^
    }                                              |
}                                                  |
// This line has the compile issue  ---------------+

上記の行で、次のコンパイル エラーが発生します。

'< null >' と 'System.DateTime' の間に暗黙的な変換がないため、条件式のタイプを決定できません

パラメーターが null 許容型 (DateTime?) であるため、混乱しています。そもそもなぜ変換する必要があるのでしょうか?null の場合はそれを使用し、日付時刻の場合はそれを使用します。

私は次のような印象を受けました。

condition ? first_expression : second_expression;

次と同じでした:

if (condition)
   first_expression;
else
   second_expression;

明らかにそうではありません。この背後にある理由は何ですか?

(注記:「myDateTime」を null 許容の DateTime にすれば機能することはわかっています。しかし、なぜそれが必要なのでしょうか?

先ほども述べたように、これは不自然な例です。実際の例では、「myDateTime」はデータ マップされた値であり、null 値を許可することはできません。)

役に立ちましたか?

解決

コンパイラは、条件演算子の結果の型を結果の使用方法からではなく、引数の型から推測します。コンパイラは、結果の型を推測できないため、この式を見つけると失敗します。

IsDateTimeHappy(myDateTime) ? null : myDateTime;

以来 null そして DateTime 互換性がない場合は、型をコンパイラに伝える必要があります。キャストはそのトリックを行う必要があります。

DateTime? x = IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime;
OutputDateTime(x);

これで、コンパイラには問題がなくなりました。必要に応じて、上記を 1 行で記述することもできます (ただし、私はおそらくこれはしません)。

OutputDateTime(IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime);

エリック・リッパートは、 いい答えだ これはここでも関連しており、コンパイラーが型を決定する方法について詳しく説明します。

他のヒント

は理由は、三項演算子は、両方のオペランドが同じタイプであることが期待されます。それが結果に割り当てられる前に、コンパイラは結果の型が何であるかを知ることができないので、全体の作業のGETは、(この場合には、関数に渡された)働いています。

IsDateTimeHappy(myDateTime) ? null : myDateTime

は上記の場合nullDateTime間の変換パスは存在しません。あなたがDateTime?にそれらのいずれかをキャストするとすぐに、コンパイラは、他の1に変換することができます:

IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime
//OR
IsDateTimeHappy(myDateTime) ? null : (DateTime?)myDateTime

作品上記のコードの拳ラインコンパイラは、暗黙の変換演算子を介してDateTimeDateTime?を変換することができるので

//In Nullable<T>
public static implicit operator T?(T value);
後者は参照型であるためnullDateTime?に割り当てることができるので、

2行目は動作します。

は、暗黙的な変換は、return文によって許可されていません。あなたが持っていた場合は、

if (condition)
    return first_expression;
else
    return second_expression;

次に、あなたはリンゴにリンゴを比較することと思います。そして、あなたは問題ないと思います - あなたが述べたように、

。 非NULL可能値型である - あなたのケースでは、あなたは、DateTimeのため、スタック上のように多くのスペースが割り当てられています。あなたは、コンパイラにどんな意味がない文を作っているので。あなたが言うなら、私はあなたにAまたはB、その後、Aと同じものになるためにB必要性を渡すつもりです。あなたのケースでは、BAになることはありません。

私は、これがここにも答えていると思います。 のNullable型と三項演算子:理由は `? 10:?null`なので、禁止する

あなたが必要なものです。

希望。 =

どのようなコンパイラが言っていることはあります:

  IsDateTimeHappy(myDateTime)falseある場合は、

、その後、私はDateTimeに等しい型myDateTimeの値を返す必要があります。それはtrueであれば、私は値を返しnullに等しくする必要がありますが、あなたはそれがあるべきタイプ何を私に言っていない!

Markの答えは解決策である理由です。あなたは、同じタイプの条件がtrueであれば、それはtruefalse戻り値をに変換できるかどうかを確認します(またはである)ことができます返される値の種類ます。

コンパイラに伝えるキャストを提供した後、

乾杯マーク! ; - )

代わりnull使用default(DateTime?)

、次いで三の両側に互換性のある型を持っています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top