web-dev-qa-db-ja.com

Nullable <value>タイプでの条件付き演算子の割り当て?

EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : Convert.ToInt32(employeeNumberTextBox.Text),

このようなことをしたいと思うことがよくあります(EmployeeNumberNullable<int>これは、列がNULL値を許可するLINQ-to-SQL dbmlオブジェクトのプロパティであるためです。残念ながら、コンパイラは「null」と「int」の間の暗黙の変換は存在しないと感じていますが、どちらの型もそれ自体でnull可能なintへの代入演算では有効です。

Nullでない場合に.Text文字列で発生する必要があるインライン変換のため、nullの合体演算子は私が見る限りでは選択肢になりません。

私が知る限り、これを行う唯一の方法は、ifステートメントを使用するか、2つのステップで割り当てることです。この特定のケースでは、オブジェクト初期化子構文を使用したかったため、この割り当てが初期化ブロック内にあるため、非常にイライラします...

誰もがよりエレガントなソリューションを知っていますか?

57
Grank

この問題が発生するのは、条件演算子が値の使用方法(この場合は割り当てられている)を調べて、式のタイプを判別するのではなく、true/falseの値だけだからです。この場合、nullInt32があり、タイプを判別できません(実際の理由があります) Nullable <Int32>)と仮定することはできません。

この方法で本当に使用したい場合は、値の1つをNullable <Int32>に自分でキャストする必要があります。これにより、C#でタイプを解決できます。

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? (int?)null
    : Convert.ToInt32(employeeNumberTextBox.Text),

または

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text),
65
Alex Lyman

ユーティリティメソッドは、これをよりクリーンにするのに役立つと思います。

public static class Convert
{
    public static T? To<T>(string value, Converter<string, T> converter) where T: struct
    {
        return string.IsNullOrEmpty(value) ? null : (T?)converter(value);
    }
}

その後

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse);
8
NerdFury

アレックスがあなたの質問に正確で近位の答えを提供しますが、私はTryParseを使用することを好みます:

_int value;
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value)
    ? (int?)value
    : null;
_

安全で、無効な入力の場合や空の文字列のシナリオに対応します。それ以外の場合、ユーザーが_1b_のようなものを入力すると、Convert.ToInt32(string)で発生した未処理の例外を含むエラーページが表示されます。

6
user13493

変換の出力をキャストできます。

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)
3
Abe Heidebrecht
//Some operation to populate Posid.I am not interested in zero or null
int? Posid = SvcClient.GetHolidayCount(xDateFrom.Value.Date,xDateTo.Value.Date).Response;
var x1 = (Posid.HasValue && Posid.Value > 0) ? (int?)Posid.Value : null;

編集:上記の簡単な説明、私はPosidの値を取得しようとしていました(その値がnull以外でintで、値が0より大きい場合)変数X1(int?) オン Posid.Value条件付き演算子がコンパイルエラーをスローしないようにします。 FYI GetHolidayCountWCFメソッドであり、nullまたは任意の数値を与えることができます。それが役に立てば幸い

1
Sandeep