サーチ…
備考
キャスティングはコンバートと同じではありません。文字列値"-1"
を整数値( -1
)に変換することは可能ですが、 Convert.ToInt32()
やInt32.Parse()
などのライブラリメソッドを使用して行う必要があります。キャスト構文を直接使用することはできません。
オブジェクトを基本型にキャストする
以下の定義が与えられた場合:
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
明示的キャスティング
値が特定の型であることがわかっている場合、その型が必要なコンテキストで使用するために、その型に明示的にキャストできます。
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
になりnull
。
object value = "-1";
int? number = value as int?;
if(number != null)
{
Console.WriteLine(Math.Abs(number.Value));
}
null
値には型がないので、 null
値をキャストするときにas
キーワードが安全にnull
as
返すことに注意してください。
暗黙のキャスティング
コンパイラが常にその型に変換できることがわかっている場合、値は自動的に適切な型にキャストされます。
int number = -1;
object value = number;
Console.WriteLine(value);
この例では、典型的な明示的キャスト構文を使用する必要はありませんでした。なぜなら、コンパイラはすべてのint
がobject
sにキャストできることを知っているからです。実際には、変数の作成を避け、 -1
を、 object
を期待するConsole.WriteLine()
引数として直接渡すことができobject
。
Console.WriteLine(-1);
キャストなしの互換性のチェック
値の型が指定された型を拡張または実装するかどうかを知る必要があるが、実際に型をその型としてキャストしたくない場合は、 is
演算子を使用できます。
if(value is int)
{
Console.WriteLine(value + "is an int");
}
明示的な数値変換
明示的なキャスト演算子を使用して、数値型の変換を実行することはできますが、それらは互いに拡張または実装しません。
double value = -1.1;
int number = (int) value;
宛先タイプの精度が元のタイプよりも低い場合、精度は失われます。たとえば、上記の例ではdouble値として-1.1
整数値として-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)
あるいは、これらの演算子を暗黙的に変更して、構文をはるかに簡単にすることができます。
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では、 Enumerable.Cast<>()
およびEnumerable.OfType<>()
拡張メソッドを使用して、 IEnumerable<>
のコンパイル時ジェネリック型を変更するプロジェクションを作成できます。
IEnumerable<IThing> things = new IThing[] {new Thing()};
IEnumerable<Thing> things2 = things.Cast<Thing>();
IEnumerable<Thing> things3 = things.OfType<Thing>();
ときthings2
評価され、 Cast<>()
メソッドは、中にすべての値をキャストしようとするthings
にThing
秒。キャストできない値がInvalidCastException
と、 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();