鋳造

# オブジェクトを基本型にキャスト

以下の定義が与えられた場合:

public interface IMyInterface1
{
    string GetName();
}

public interface IMyInterface2
{
    string GetName();
}

public class MyClass : IMyInterface1, IMyInterface2
{
    string IMyInterface1.GetName()
    {
        return "IMyInterface1";
    }

    string IMyInterface2.GetName()
    {
        return "IMyInterface2";
    }
}

オブジェクトを基本型にキャストする例:


   MyClass obj = new MyClass();

    IMyInterface1 myClass1 = (IMyInterface1)obj;
    IMyInterface2 myClass2 = (IMyInterface2)obj;

    Console.WriteLine("I am : {0}", myClass1.GetName());
    Console.WriteLine("I am : {0}", myClass2.GetName());

    // Outputs :
    // I am : IMyInterface1
    // I am : IMyInterface2

# キャストせずに互換性をチェックする

値の型が特定の型を拡張または実装するかどうかを知る必要があるが、実際にはその型としてキャストしたくない場合は、 is を使用できます

if(value is int)
{
   Console.WriteLine(value + "is an int");
}

# 明示的なキャスト

値が特定の型であることがわかっている場合は、その型が必要なコンテキストで使用するために、その型に明示的にキャストできます。

object value = -1;
int number = (int) value;
Console.WriteLine(Math.Abs(number));

value を渡そうとしたら Math.Abs() に直接 Math.Abs() であるため、コンパイル時に例外が発生します。 object を取るオーバーロードがありません パラメータとして。

value の場合 int にキャストできませんでした の場合、この例の 2 行目は InvalidCastException をスローします。

# 安全な明示的キャスト (as オペレーター)

値が思った通りの型かどうかわからない場合は、as を使用して安全にキャストできます。 オペレーター。値がそのタイプでない場合、結果の値は null になります .

object value = "-1";
int? number = value as int?;
if(number != null)
{
    Console.WriteLine(Math.Abs(number.Value));
}

null に注意してください 値には型がないため、as キーワードは安全に null を生成します null をキャストするとき

# 暗黙のキャスト

コンパイラが常に適切な型に変換できることを認識している場合、値は自動的に適切な型にキャストされます。

int number = -1;
object value = number;
Console.WriteLine(value);

この例では、コンパイラはすべての int を認識しているため、典型的な明示的なキャスト構文を使用する必要はありませんでした。 s は object にキャストできます 秒。実際、変数の作成を避けて -1 を渡すことができました Console.WriteLine() の引数として直接 object を期待する .

Console.WriteLine(-1);

# 明示的な数値変換

明示的なキャスト演算子は、相互に拡張または実装していなくても、数値型の変換を実行するために使用できます。

double value = -1.1;
int number = (int) value;

宛先の型の精度が元の型よりも低い場合、精度が失われることに注意してください。例:-1.1 上記の例の double 値は -1 になります。 整数値として。

また、数値変換はコンパイル時の型に依存するため、数値型がオブジェクトに「ボックス化」されている場合は機能しません。

object value = -1.1;
int number = (int) value; // throws InvalidCastException

# 変換演算子

C# では、型はカスタム 変換演算子 を定義できます これにより、明示的または暗黙的なキャストを使用して、値を他の型との間で変換できます。たとえば、JavaScript 式を表すクラスを考えてみましょう:

public class JsExpression
{
    private readonly string expression;
    public JsExpression(string rawExpression)
    {
        this.expression = rawExpression;
    }
    public override string ToString()
    {
        return this.expression;
    }
    public JsExpression IsEqualTo(JsExpression other)
    {
        return new JsExpression("(" + this + " == " + other + ")");
    }
}

2 つの JavaScript 値の比較を表す JsExpression を作成したい場合は、次のようにすることができます。

JsExpression intExpression = new JsExpression("-1");
JsExpression doubleExpression = new JsExpression("-1.0");
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)

ただし、明示的な変換演算子をいくつか追加できます JsExpression へ 、明示的なキャストを使用するときに簡単な変換を可能にします。

public static explicit operator JsExpression(int value)
{
    return new JsExpression(value.ToString());
}
public static explicit operator JsExpression(double value)
{
    return new JsExpression(value.ToString());
}

// Usage:
JsExpression intExpression = (JsExpression)(-1);
JsExpression doubleExpression = (JsExpression)(-1.0);
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)

または、これらの演算子を implicit に変更することもできます 構文をより単純にするためです。

public static implicit operator JsExpression(int value)
{
    return new JsExpression(value.ToString());
}
public static implicit operator JsExpression(double value)
{
    return new JsExpression(value.ToString());
}

// Usage:
JsExpression intExpression = -1;
Console.WriteLine(intExpression.IsEqualTo(-1.0)); // (-1 == -1.0)

# LINQ キャスト操作

次のような型があるとします:

interface IThing {  }
class Thing : IThing {  }

LINQ では、IEnumerable<> のコンパイル時のジェネリック型を変更するプロジェクションを作成できます。 Enumerable.Cast<>() 経由 と Enumerable.OfType<>() 拡張メソッド。

IEnumerable<IThing> things = new IThing[] {new Thing()};
IEnumerable<Thing> things2 = things.Cast<Thing>();
IEnumerable<Thing> things3 = things.OfType<Thing>();

things2の場合 Cast<>() が評価されます メソッドは things のすべての値をキャストしようとします Thing に 秒。キャストできない値に遭遇した場合、InvalidCastException

things3 の場合 OfType<>() が評価されます メソッドは同じことを行いますが、キャストできない値に遭遇した場合、例外をスローするのではなく、単にその値を省略します。

これらのメソッドはジェネリック型であるため、変換演算子を呼び出したり、数値変換を実行したりすることはできません。

double[] doubles = new[]{1,2,3}.Cast<double>().ToArray(); // Throws InvalidCastException

.Select() 内でキャストを実行するだけです 回避策:

double[] doubles = new[]{1,2,3}.Select(i => (double)i).ToArray();

# コメント

キャスティング コンバージョンとは異なります .文字列値 "-1" を変換することが可能です 整数値 (-1 )、しかしこれは Convert.ToInt32() のようなライブラリ メソッドを介して行う必要があります または Int32.Parse() .キャスト構文を直接使用して行うことはできません。