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-07-24

이것은 "데이터 유형 찾기"가 의미하는 바가 명확하지 않습니다. 일반적으로 대답은 "클래스 멤버 시그니처를보고 유형이 명시 적으로 명시되어 있습니다"입니다. 런타임에 클래스 멤버를 검사하려는 의도입니까?
Wiktor Zychla

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; } }. Properties에
Steve B

1
Jamiec이 옳습니다. 정적 유형은 선언이 유형을 영원히 설정 함을 의미합니다. 변수 n은 선언 한 유형 또는 상속 된 유형 만 될 수 있습니다. 특정 경우에 int를 표시하기로 선택한 경우 상속 할 수없는 유형이므로 n은 int 만 될 수 있습니다.
Ksempac

답변:


119

그들 중 누구도 직접 다루지 않는 중요하고 미묘한 문제가 있습니다. C #에서 유형을 고려하는 방법에는 정적 유형런타임 유형 의 두 가지가 있습니다 .

정적 유형 은 소스 코드의 변수 유형입니다. 따라서 이것은 컴파일 타임 개념입니다. 개발 환경에서 변수 또는 속성 위로 마우스를 가져 가면 도구 설명에 표시되는 유형입니다.

헬퍼 제네릭 메서드를 작성하여 정적 유형을 얻을 수 있습니다.

   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

같은 값 형 변수의 경우 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));

3
그래서 variable.getType()런타임 유형 (오른쪽 유형)을 반환하지만 정적 유형 (변수의 왼쪽 유형)을 반환하는 것은 무엇입니까?
barlop

컴파일 타임에 알려진 @barlop. typeof정적 유형에 대해 런타임에 유형 객체를 가져 오는 데 사용할 수 있습니다 .
phoog

예, 정적 유형 = 컴파일 시간 유형 및 런타임 유형 = 동적 유형을 알고 있습니다. 변수 'a'의 유형을 가져 오더라도 int를 반환 typeof(a) 하면 할 typeof(int)수 없지만 변수 'a'를 확인하지 않고 'a'의 유형을 표시하지 않습니다. 'a'의 정적 유형을 표시 할 필요는 없습니다. 그럴 수도 있지만 사실은 표시하지 않습니다. 그래서 여기서 typeof 사용이 얼마나 유용한 지 모르겠습니다.
barlop dec

4
당신은 당신을 위해 그것의 형식 유추 돌봐을 수 있도록이 작업을 수행 할 수 @barlop :Type GetStaticType < T > (T x) { return typeof(T); }
phoog

1
알다시피 @Jaquarh는 switch이제 유형 테스트 (정적이 아닌 런타임 유형)를위한 패턴 일치를 지원합니다. GetType ()에서 반환 된 값을 전환하는 대신 변수를 직접 전환합니다.
phoog

17

매우 간단합니다

variable.GetType().Name

변수의 데이터 유형을 반환합니다.


16

일반적으로 리플렉션이나 인터페이스를 사용하지 않는 한 유형 비교를 할 필요가 거의 없습니다. 그럼에도 불구하고:

비교할 유형을 알고있는 경우 is또는 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();
}

4

관심있는 회원 위에 커서를 올려 놓고 툴팁을 확인하면 회원 유형이 표시됩니다.

여기에 이미지 설명 입력



3

한 가지 옵션은 다음과 같은 도우미 확장 방법을 사용하는 것입니다.

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

이 작업을 수행하는 간단한 방법 중 하나를 확인하십시오.

// 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.