1. ホーム
  2. c#

[解決済み] C#で変数のデータ型を取得するにはどうしたらいいですか?

2022-05-17 17:02:57

質問

ある変数が保持しているデータ型を調べるにはどうしたらよいでしょうか。(例:int, string, char, など)

今、こんなのがあります。

private static void Main()
{
   var someone = new Person();
   Console.WriteLine(someone.Name.typeOf());
}

public class Person
{
    public int Name { get; set; }
}

どのように解決するのですか?

他の回答はこの質問に対して良い手助けをしてくれますが、重要で微妙な問題があり、どれも直接的には解決していません。 C# で型を考慮する方法は 2 つあります。 静的型 ランタイム型 .

静的型とは、ソースコード上の変数の型です。 したがって、コンパイル時の概念です。 開発環境で変数やプロパティにカーソルを合わせるとツールチップで表示される型です。

ランタイム型は、メモリ上のオブジェクトの型です。 そのため、ランタイム概念となります。 これは GetType() メソッドによって返される型です。

オブジェクトの実行時型は、それを保持したり返したりする変数、プロパティ、メソッドの静的型と異なることがよくあります。 例えば、次のようなコードがあります。

object o = "Some string";

変数の静的型は object ですが、実行時にはこの変数の型である 参照 string . したがって、次の行はコンソールに "System.String" と表示されます。

Console.WriteLine(o.GetType()); // prints System.String

しかし、変数の上にカーソルを置くと o という変数にカーソルを合わせると、開発環境では System.Object (または同等の object キーワード)。

のような値型変数では int , double , System.Guid なぜなら、値型は他の型の基底クラスとして機能しないからです。値型は、その継承連鎖の中で最も派生した型であることが保証されています。 これはシールされた参照型にも当てはまります。静的型がシールされた参照型の場合、実行時の値はその型のインスタンスか、あるいは null .

逆に言えば、変数の静的型が抽象型であれば、静的型と実行時型が異なることが保証されていることになります。

それをコードで説明すると

// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));

// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));

// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));

// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));


別のユーザーがこの回答を編集して、コメントに表示されている関数、つまり実行時に変数の静的型への参照を取得するために型推論を使用する汎用ヘルパー メソッドを組み込んでいます、おかげで typeof :

Type GetStaticType<T>(T x) => typeof(T);

この関数は、上の例で使うことができます。

Console.WriteLine(GetStaticType(o)); // prints System.Object

しかし、リファクタリングから身を守りたいのでなければ、この関数の有用性は限られたものです。 への呼び出しを書いているとき GetStaticType の呼び出しを書いているとき、あなたはすでに o の静的型がオブジェクトであることを知っています。 あなたは

Console.WriteLine(typeof(object)); // also prints System.Object!

これは、私が今の仕事を始めたときに遭遇した、次のようなコードを思い出させます。

SomeMethod("".GetType().Name);

の代わりに

SomeMethod("String");