私はしばらくの間、いくつかのコードに取り組んできました。質問がありました: キャスト、解析、変換の違いは何ですか? そして、いつそれらを使用できますか?
7 に答える
キャストとは、ある型の変数を別の型に変更することです。次のような場合にのみ、これを行うことができます。
string str = "Hello";
object o = str;
string str2 = (string)o; // <-- This is casting
キャストによって変数の値が変更されることはありません。値は同じ型 (文字列 "Hello") のままです。
変換とは、ある型から値を取得して別の型に変換することです。
double d = 5.5;
int i = (int)d; // <---- d was converted to an integer
この場合、変換はキャストの形で行われたことに注意してください。
解析とは、文字列を取得し、その内容を理解して別の型に変換することです。たとえば、文字列 "123" を数値 123 に変換したり、文字列 "Saturday, September 22nd" を DateTime に変換したりします。
キャスト: オブジェクトを変更せずに、実際には別のものであることをコンパイラーに伝えます (ただし、一部のデータ損失が発生する可能性があります)。
object obj_s= "12345";
string str_i = (string) obj; // "12345" as string, explicit
int small = 12345;
long big = 0;
big = small; // 12345 as long, implicit
解析: (実行時に) 文字列を解釈するようにプログラムに指示します。
string int_s = "12345";
int i = int.Parse(int_s); // 12345 as int
Converting : 組み込みメソッドを使用して、単純に交換可能ではない可能性のある型を変更しようとするようにプログラムに指示します。
double dub = 123.45;
int i = System.Convert.ToInt32(dub); // 123 as int
これらは、それぞれ特定の用途を持つ 3 つの用語です。
- キャスト - 1 つ
type
を別のものに変更します。これを行うには、型に互換性がなければなりません:int
->object
;IList<T>
->IEnumerable<T>
- 解析 - 通常、文字列を読み取って有用な部分を抽出することを指します
- 変換 - キャストに似ていますが、通常、変換には 1 つの型を互換性のない型に変更することが含まれます。その例は、オブジェクトを文字列に変換することです。
ある型から別の型へのキャストには、通常、継承またはインターフェイスの実装を介して、何らかの形式の互換性が必要です。キャストは暗黙的または明示的に行うことができます。
class Foo : IFoo {
// implementations
}
// implicit cast
public IFoo GetFoo() {
return Foo;
}
// explicit cast
public IFoo GetFoo() {
return Foo as IFoo;
}
解析する方法はかなりあります。XML 解析について読みました。一部の型にはParse
andTryParse
メソッドがあります。そして、「関心のあるもの」を抽出するために、文字列やその他の型を解析する必要がある場合があります。
int.Parse("3") // returns an integer value of 3
int.TryParse("foo", out intVal) // return true if the string could be parsed; otherwise false
変換には、あるタイプを互換性のない別のタイプに変更する必要がある場合があります。これには、いくつかの解析も含まれる場合があります。変換の例は通常、IMO であり、特定のコンテキストに非常に関連しています。
人によって、意味が異なります。.net の世界以外では真実である必要はありませんが、Eric Lippert のブログを読んで .net のコンテキストで理解したことは次のとおりです。
ある形式から別の形式への型のすべての変換は、変換と呼ばれます。分類の 1 つの方法として、
暗黙の -
a. 表現の変更(強制とも呼ばれる)
int i = 0; double d = i; object o = i; // (specifically called boxing conversion) IConvertible o = i; // (specifically called boxing conversion)
暗黙的な変換演算子が必要です。変換は常に成功し (暗黙的な変換演算子は決してスローしないでください)、変換されるオブジェクトの参照 ID を変更します。
b. 表現の保存(暗黙の参照変換とも呼ばれます)
string s = ""; object o = s; IList<string> l = new List<string>();
参照型に対してのみ有効で、変換されるオブジェクトの参照 ID を変更することはありません。変換は常に成功し、コンパイル時に保証され、実行時チェックは行われません。
明示的(キャストとも呼ばれる) -
a. 表現の変更
int i = 0; enum e = (enum)i; object o = i; i = (int)o; // (specifically called unboxing conversion)
明示的な変換演算子を必要とし、変換されるオブジェクトの参照 ID を変更し、変換が成功する場合と失敗する場合があり、ランタイムで互換性をチェックします。
b. 表現の保存 (明示的な参照変換とも呼ばれます)
object o = ""; string s = (string)o;
参照型に対してのみ有効で、変換されるオブジェクトの参照 ID を変更しません。変換が成功する場合と失敗する場合があります。互換性について実行時チェックを行います。
変換は言語レベルの構成要素ですが、Parseはフレームワーク レベルであるという意味で大きく異なります。つまり、入力から出力を取得するために記述されたカスタム メソッドint.Parse
であり、 を受け取ってstring
を返しますint
。
この質問は実際にはかなり複雑です...
通常、キャストは、ある型を別の型に変更するようにランタイムに指示するだけです。これらは、互換性のある型である必要があります。たとえば、int
は常に として表すことができるlong
ので、 にキャストしても問題ありませんlong
。一部のキャストには副作用があります。たとえば、 afloat
にキャストすると、 a の精度が低下しint
ます。したがって(int)1.5f
、int 値 1 になります。キャストは、単一の IL 演算子であるため、通常、型を変更する最速の方法です。たとえば、コードは次のとおりです。
public void CastExample()
{
int i = 7;
long l = (long)i;
}
IL コードを実行してキャストを実行します。
conv.i8 //convert to 8-byte integer (a.k.a. Int64, a.k.a. long).
パースは、ある型を取り込んで別の型を返す関数です。これは単なる IL 演算子ではなく、実際のコード関数です。これは複数行のコードを実行するため、通常は実行に時間がかかります。
たとえば、次のコード:
public void ParseExample()
{
string s = "7";
long l = long.Parse(s);
}
IL コードを実行します。
call int64 [mscorlib]System.Int64::Parse(string)
つまり、実際のメソッドを呼び出します。内部的には、Int64 型がそのメソッドを提供します。
public static long Parse(String s) {
return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
そして Number.Parse:
[System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
if ((options & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToInt64(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
}
}
else {
if (!NumberToInt64(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
}
}
return i;
}
などなど...実際に多くのコードを実行していることがわかります。
ここで事態がさらに複雑になるのは、キャストは通常最も高速ですが、クラスは暗黙的および明示的なキャスト演算子をオーバーライドできることです。たとえば、クラスを書くと:
public class CastableClass
{
public int IntValue { get; set; }
public static explicit operator int(CastableClass castable)
{
return castable.IntValue;
}
}
の明示的なキャスト演算子をオーバーライドしたint
ので、次のことができるようになりました。
public void OverridedCastExample()
{
CastableClass cc = new CastableClass {IntValue = 7};
int i = (int)cc;
}
これは通常のキャストのように見えますが、実際にはクラスで定義したメソッドを呼び出します。IL コードは次のとおりです。
call int32 UnitTestProject1.CastableClass::op_Explicit(class UnitTestProject1.CastableClass)
とにかく、通常は可能な限りキャストしたいと考えています。できない場合は解析します。
キャスト (型を機能させるには互換性が必要です) データ型間の変換は、キャストを使用して明示的に行うことができます
static void _Casting()
{
int i = 10;
float f = 0;
f = i; // An implicit conversion, no data will be lost.
f = 0.5F;
i = (int)f; // An explicit conversion. Information will be lost.
}
解析 (解析は異なる型間の変換です:) ある型を別の型に変換することは、 int.parse を使用して解析として呼び出すことができます
int num = int.Parse("500");
XML のようなデータ項目をトラバースすることは、解析とも呼ばれます。
ユーザー定義の変換が関係する場合、通常は異なるオブジェクト/値を返す必要があります。ユーザー定義の変換は通常、参照型ではなく値型の間に存在するため、これが問題になることはめったにありません。
Convert-class を使用すると、実際にはそれを解析するのに役立ちます
詳細については、http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspxを参照してください。
キャスト:または解析
キャストは、ある型から別の型への変換演算子を明示的に呼び出します。変数のキャストは単純ではありません。複雑な一連のルールによってキャストが解決されます。場合によっては、データが失われ、キャストを元に戻すことができなくなります。また、実行エンジンで例外が発生する場合もあります。
int.Parse
は最も単純な方法ですが、無効な入力に対して例外をスローします。
int.TryParse
は、C# 言語で整数を解析するための最も便利な方法の 1 つです。このメソッドは と同じように機能しint.Parse
ます。
int.TryParse
内部にtry and catch構造があります。したがって、例外はスローされません
基本データ型を別の基本データ型に変換します。Convert.ToInt32 は、その兄弟である Convert.ToInt16 および Convert.ToInt64 と共に、実際には int.Parse メソッドの静的ラッパー メソッドです。
orTryParse
の代わりに使用することは、多くのプログラマーによって推奨されています。Convert
Cast
ソース: www.dotnetperls.com