C#で変数のデータ型を取得するにはどうすればよいですか?


92

変数が保持しているデータ型を確認するにはどうすればよいですか?(例:int、string、charなど)

私は今このようなものを持っています:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Testing
{
    class Program
    {
        static void Main()
        {
            Person someone = new Person();
            someone.setName(22);
            int n = someone.getName();
            Console.WriteLine(n.typeOf());
        }
    }

    class Person
    {
        public int name;

        public void setName(int name)
        {
            this.name = name;
        }

        public int getName()
        {
            return this.name;
        }
    }
}

6
タイプはすでに定義されていますint
Jamiec、2012

これは、「データ型を見つける」という意味が明確ではありません。通常、答えは「クラスメンバーのシグネチャを見て、型はそこに明示的に記述されている」です。実行時にクラスメンバーを検査するつもりですか?
Wiktor Zychla、2012

1
主題外ですが、ここで書いたものは、C#:class Person { public string Name { get; set; } }またはでこのように書く方が適切ですclass Person { private string m_Name; public string Name { get {return m_Name;} set { m_Name = value; } }プロパティ
Steve B

1
ジャミエックはそうです。静的型付けとは、宣言によって型が永久に設定されることを意味します。変数nは、宣言した型または継承された型のみにすることができます。特定のケースでは、intを表示することを選択しました。これは継承できないタイプであるため、nはintのみにすることができます。
Ksempac 2012

回答:


116

それらのどれも直接対処しない重要で微妙な問題があります。C#で型を検討するには、静的型実行時型の 2つの方法があります。

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

ヘルパージェネリックメソッドを記述して静的型を取得し、型推論で静的型を処理できるようにします。

   Type GetStaticType<T>(T x) { return typeof(T); }

実行時タイプは、メモリ内のオブジェクトのタイプです。したがって、これは実行時の概念です。これは、GetType()メソッドによって返されるタイプです。

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

object o = "Some string";

変数の静的型はですがobject、実行時に変数の参照先の型はstringです。したがって、次の行は「System.String」をコンソールに出力します。

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

ただし、o開発環境で変数にカーソルを合わせると、タイプSystem.Object(または同等のobjectキーワード)が表示されます。上記のヘルパー関数を使用しても同じことがわかります。

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

以下のような値型の変数についてはintdoubleSystem.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));

3
その variable.getType()実行時の型(右側タイプ)が返されますが、どのような静的タイプ(変数の左側のタイプ)を返しますか?
barlop

コンパイル時に既知である@barlop。を使用typeofして、静的型の実行時に型オブジェクトを取得できます。
phoog 2015

はい、静的型=コンパイル時型、実行時型=動的型を知っています。変数 'a'の型を取得していtypeof(a) ますが、typeof(int)それがintを返す場合は実行できませんが、変数 'a'をチェックして 'a'の型を表示していません。 「a」の静的タイプを表示する必要はありませんが、そうである可能性がありますが、実際には表示されていません。したがって、typeofの使用がどのように役立つかはわかりません。
barlop

4
あなたはあなたのためにそれの型推論の世話をできるようにこれを行うことができます@barlop:Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
お気づきかもしれませんが、@ Jaquarhはswitch(静的ではなくランタイムタイプの)タイプテストのパターンマッチングをサポートするようになりました。GetType()から返された値をオンにする代わりに、変数を直接オンにします。
phoog


16

一般的に言って、リフレクションやインターフェースで何かをしているのでなければ、型の比較をする必要はほとんどありません。それにもかかわらず:

比較するタイプがわかっている場合は、isor as演算子を使用します。

if( unknownObject is TypeIKnow ) { // run code here

asオペレータは、リターンが、それは例外ではなく、失敗した場合はnullというキャストを実行します。

TypeIKnow typed = unknownObject as TypeIKnow;

タイプがわからず、実行時のタイプ情報だけが必要な場合は、.GetType()メソッドを使用します。

Type typeInformation = unknownObject.GetType();

C#の新しいバージョンでは、is演算子を使用して変数を宣言できます。使用する必要はありませんas

if( unknownObject is TypeIKnow knownObject ) {
    knownObject.SomeMember();
}

以前はこれを行う必要がありました:

TypeIKnow knownObject;
if( (knownObject = unknownObject as TypeIKnow) != null ) {
    knownObject.SomeMember();
}



3

1つのオプションは、次のようなヘルパー拡張メソッドを使用することです。

public static class MyExtensions
{
    public static System.Type Type<T>(this T v)=>typeof(T);
}

var i=0;
console.WriteLine(i.Type().FullName);

0

GetType() 方法

int n=34;
Console.WriteLine(n.GetType());
string name="Smome";
Console.WriteLine(name.GetType());

0

これを行う簡単な方法の1つを確認してください

// Read string from console
        string line = Console.ReadLine(); 
        int valueInt;
        float valueFloat;
        if (int.TryParse(line, out valueInt)) // Try to parse the string as an integer
        {
            Console.Write("This input is of type Integer.");
        }
        else if (float.TryParse(line, out valueFloat)) 
        {
            Console.Write("This input is of type Float.");
        }
        else
        {
            Console.WriteLine("This input is of type string.");
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.