質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

Q&A

解決済

3回答

467閲覧

newする型名を動的に判別したい

tarot_shogun

総合スコア29

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

0グッド

2クリップ

投稿2019/03/26 15:21

編集2019/03/30 10:39

どのようなコードを記述すれば下記の要求を満たせるでしょうか。
お力添えいただけると幸いです。

<要求>
リストに格納されているobjectの値が全てゼロ相当であることを確認するプログラム。
※0相当: intなら0, stringなら"0", TimeSpanなら"00:00:00"

<前提条件>
object に格納されている型はint, double, string, TimeSpan, (null)のいずれかです。

<試行錯誤>
私が考えたコードは以下の通りです。
しかし、type = TimeSpanのときにキャストエラーが発生し、下記のコードは動作しません。

C#

1 bool isBlank = ObjectList.All(x => 2 { 3 x = x ?? 0; 4 return x == Convert.ChangeType(0, x.GetType()); 5 });

他にも以下のようなコードを考えましたが動きませんでした。

C#

1 bool isBlank = ObjectList.All(x => 2 { 3 x = x ?? 0; 4 type = x.GetType(); 5 return x == new type(0); 6 });

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

私は短くさっぱり書きたい人なので、switch-case文は可能(かつ可読性が落ちない)ならDictionaryにしちゃってます。

Dictionary<Type, object> zeroValues = new Dictionary<Type, object>() { { typeof(int), 0 }, { typeof(string), "0" }, { typeof(TimeSpan), new TimeSpan(0) }, }; bool isBlank = ObjectList.All(x => x == null ? true : zeroValues[x.GetType()].Equals(x));

比較する値の種類が増えた場合にこれなら1行の追加で済むというのがメリット、Equalsで比較できないものを追加したい場合に判定式を変える必要があり、全ての値に影響するというのがデメリットですかね。

投稿2019/03/27 00:40

moredeep

総合スコア1507

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tarot_shogun

2019/03/30 11:08 編集

ご回答ありがとうございます。連想配列を使用するとこんなに綺麗に書けるんですね。 大変参考になりました。
draq

2019/03/31 04:14

Equalsで比較できないケースも考えるなら、ディクショナリの値はFunc<object,bool>にして0かどうかの判断するメソッドをデリゲートとしてディクショナリで管理するとか。
guest

0

  • なぜ型の混成されたリストを処理するのか。
  • その後に出力される形式はどのようなものが望ましいか
  • Null時の真偽判定はどちらか

という内容が抜けているため、正確な回答ができないかと思われ間s。

ただし、C#7.1以降ではSwitch構文で型を指定したコードが使用できるため次のサンプルを用意しました。
ざっくりとした要求仕様にはお答えできるかと思われますがいかがでしょうか?

CSharp

1 2 class Program 3 { 4 static void Main(string[] args) 5 { 6 var list = new List<object> 7 { 8 0,"0",new TimeSpan(0), null,1 9 }; 10 11 list.Select(IsDefault).ToList().ForEach(Console.WriteLine); 12 13 Console.ReadKey(); 14 } 15 16 static bool IsDefault<T>(T arg) 17 { 18 if (arg == null) 19 { 20 return false; 21 } 22 23 switch (arg) 24 { 25 case int caseInt: 26 return caseInt == 0; 27 case string caseString: 28 return caseString == "0"; 29 case TimeSpan caseTimeSpan: 30 return caseTimeSpan == new TimeSpan(0); 31 default: 32 return false; 33 } 34 35 } 36 }

投稿2019/03/26 17:16

Argent

総合スコア59

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/03/26 23:05

if (arg == null) でコンパイルエラー出ませんか? また質問のコードを見る限り null は 0 と判定してほしいようです。
Zuishin

2019/03/27 12:27

実際にやってみるとエラー出ませんね。失礼しました。
tarot_shogun

2019/03/30 11:10 編集

ご回答ありがとうございます。 長くなると思い質問文には記載しませんでした。 Epplusを使用してエクセルの空白をチェックするメソッドを作成しております。 当初、セルが空白の場合は値がnullになっていると踏んでおりましたが、 nullではなく0が格納されている場合もあることを知りました。 そこで、0を空白とみなした処理することにしたのです。 しかし、セルの値はバラバラでstringの場合もdoubleの場合もTimeSpanの場合もあります。 こうしたセルごとの型を考慮しないようにobject型の引数を取っています。 さらに、複数セルを一括で処理できるように引数は可変長となっています。 これが型の混成されたリスト(配列)を処理する原因にあたります。
guest

0

is 演算子を使ってはいかがでしょう? 使えない理由があれば教えてください。

投稿2019/03/26 21:46

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tarot_shogun

2019/03/30 10:42 編集

ご回答ありがとうございます。 if(typeof(TimeSpan) == x.GetType())のように分岐させるイメージで間違いないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問