C#:型変換の落とし穴を回避!直接キャストと「as」演算子の選び方

2024-07-27

C#における直接キャストと「as」演算子の比較

直接キャスト

直接キャストは、括弧の中に型を指定してオブジェクトを変換する方法です。 例えば、string型の変数をint型に変換するには、以下のように記述します。

int number = (int) "123";

直接キャストは、成功した場合、変換後の値を直接使用できます。 ただし、変換が失敗すると、実行時エラーが発生します。

「as」演算子

「as」演算子は、オブジェクトを変換し、成功した場合のみ結果を変数に代入する方法です。 例えば、object型の変数をstring型に変換するには、以下のように記述します。

string text = obj as string;

「as」演算子は、変換が失敗してもエラーが発生せず、nullが代入されます。

使い分け

直接キャストと「as」演算子は、以下の点で使い分けられます。

  • 変換の成功が確実な場合: 直接キャストを使用します。
  • null許容参照型を使用する場合: 「as」演算子を使用します。

以下の例では、直接キャストと「as」演算子の使い分けを示しています。

// 直接キャスト
string str = "123";
int number = (int) str; // 成功

// "as"演算子
object obj = 123;
string text = obj as string; // 失敗

// null許容参照型
string? name = null;
string? upperName = name?.ToUpper(); // null許容参照型とas演算子の併用



using System;

public class Sample
{
    public static void Main(string[] args)
    {
        // 直接キャスト
        string str = "123";
        int number = (int)str; // 成功
        Console.WriteLine(number); // 123

        // "as"演算子
        object obj = 123;
        string text = obj as string; // 失敗
        Console.WriteLine(text); // null

        // null許容参照型
        string? name = null;
        string? upperName = name?.ToUpper(); // null許容参照型とas演算子の併用
        Console.WriteLine(upperName); // null

        // 例外処理
        try
        {
            // 明示的なキャスト
            int invalidNumber = (int)"abc";
        }
        catch (InvalidCastException e)
        {
            Console.WriteLine(e.Message); // "文字列 'abc' は、型 'System.Int32' に変換できません。"
        }

        // "as"演算子による安全なキャスト
        object obj2 = "abc";
        int? safeNumber = obj2 as int?;
        Console.WriteLine(safeNumber); // null
    }
}

このコードを実行すると、以下の出力が得られます。

123
null
null
文字列 'abc' は、型 'System.Int32' に変換できません。
null



IConvertibleインターフェースを実装しているオブジェクトは、ToXXX()メソッドを使用してさまざまな型に変換できます。 例えば、string型のオブジェクトをint型に変換するには、以下のように記述します。

string str = "123";
int number = (int)Convert.ChangeType(str, typeof(int));

IConvertibleインターフェースは、多くの標準型でサポートされています。

ジェネリック型変換

ジェネリック型変換を使用して、オブジェクトを別の型に変換できます。 例えば、List<string>型のオブジェクトをList<int>型に変換するには、以下のように記述します。

List<string> stringList = new List<string>() { "1", "2", "3" };
List<int> intList = stringList.Select(x => int.Parse(x)).ToList();

ジェネリック型変換は、複雑な型変換に役立ちます。

特定の種類のオブジェクト変換に特化したライブラリもあります。 例えば、JSONとオブジェクト間の変換には、Newtonsoft.Jsonライブラリを使用できます。


c# casting



C#におけるStringとstringの代替方法

**C#**では、Stringとstringという2つのキーワードがありますが、実はどちらも同じものを指しています。つまり、C#ではstringがエイリアスとして定義されており、Stringとまったく同じ意味を持っています。これは、C#の設計上の選択であり、開発者がどちらのキーワードを使っても同じコードが生成されるようになっています。...


C#における[Flags] Enum属性の代替方法

**C#において、[Flags]**属性は、列挙型(enum)に対して適用される属性です。この属性は、列挙型のメンバーがビットフラグとして使用されることを示します。つまり、複数の列挙型メンバーを組み合わせることで、複数の状態やオプションを表現することができます。...


C#の隠れた機能:代替的なプログラミング手法

**C#**は、Microsoftが開発したオブジェクト指向プログラミング言語です。その多機能性と柔軟性により、さまざまなアプリケーション開発に広く使われています。しかし、その機能の豊富さゆえに、一部の機能が「隠れた」存在となることもあります。...


C#におけるDataTableに対するLINQクエリ代替方法

**LINQ (Language-Integrated Query)**は、.NET Frameworkで提供されるクエリ構文です。これにより、オブジェクトのコレクションを宣言的に操作することができます。DataTableは、データベーステーブルの構造とデータを表現するオブジェクトであり、LINQを使ってクエリを実行することができます。...


C#における基底コンストラクタ呼び出しの具体的なコード例と解説

**C#**において、クラスが別のクラスから継承している場合、そのクラスのコンストラクタは基底クラスのコンストラクタを呼び出す必要があります。これは、基底クラスの初期化が子クラスの初期化の前提となるためです。base()キーワードを使用:public class DerivedClass : BaseClass { public DerivedClass() : base() { // Derived class's constructor body } } この場合、DerivedClassのコンストラクタはBaseClassのデフォルトコンストラクタを呼び出します。...



c# casting

C#でDateTime型の誕生日から年齢を計算するコードの解説

日本語:C#でDateTime型の誕生日から年齢を計算するには、以下の手順に従います。誕生日を取得する: DateTime型の変数に誕生日の日付を設定します。現在の時刻を取得する: DateTime. Nowを使用して現在の時刻を取得します。


C#で相対時間を計算できるようになれば、あなたのプログラミングスキルが飛躍的に向上する!

DateTime 構造体は、日付と時刻を表す型です。この構造体には、相対時間を計算するためのいくつかのメソッドが用意されています。例えば、以下のコードは、現在時刻から2時間後の時刻を取得します。また、以下のコードは、2つの DateTime 構造体間の差分を取得します。


C#で辞書を値でソートするコード例

**C#**において、辞書(Dictionary)の要素を値でソートするには、通常以下の手順を踏みます。値とキーのペアを格納する新しいリストを作成する。元の辞書の各要素を新しいリストに追加する。新しいリストを値でソートする。ソートされたリストからキーと値を抽出する。


C#におけるTypeから新しいオブジェクトインスタンスを作成する際の性能比較:コード例と解説

日本語訳:C#において、Typeオブジェクトから新しいオブジェクトインスタンスを作成する方法は、パフォーマンスに影響を与えます。この解説では、さまざまな方法とその性能について説明します。Activator. CreateInstanceメソッド:


C#ループ制御: breakとcontinueの代替方法

C#のループ(forループ、whileループ、foreachループなど)において、breakとcontinueは、ループの制御に重要な役割を果たします。機能: ループの処理を即座に終了します。使用タイミング:ループの条件が満たされた場合ループ内でエラーが発生した場合特定の条件を満たしたときにループを終了したい場合