Làm cách nào để lấy kiểu dữ liệu của một biến trong C #?


92

Làm cách nào để biết một số biến đang giữ kiểu dữ liệu nào? (ví dụ: int, string, char, v.v.)

Tôi có một cái gì đó như thế này bây giờ:

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
Bạn đã định nghĩa các loại -int
— Jamiec

Điều này không rõ ràng những gì bạn có nghĩa là "tìm ra loại dữ liệu". Thông thường, câu trả lời là "bạn chỉ cần nhìn vào chữ ký của thành viên trong lớp và loại được nêu ở đó một cách rõ ràng". Bạn có ý định kiểm tra các thành viên trong lớp trong thời gian chạy không?
— Wiktor Zychla

1
Lạc đề, nhưng những gì bạn viết ở đây tốt hơn nên viết như thế này với C #: class Person { public string Name { get; set; } }or class Person { private string m_Name; public string Name { get {return m_Name;} set { m_Name = value; } }. Đọc tài liệu về thuộc tính
— Steve B

1
Jamiec đã đúng. Nhập tĩnh có nghĩa là khai báo đặt kiểu của bạn mãi mãi. Biến n của bạn chỉ có thể thuộc kiểu bạn đã khai báo hoặc kiểu kế thừa. Trong trường hợp cụ thể của bạn, bạn đã chọn hiển thị một int, đó là kiểu bạn không thể kế thừa, vì vậy n chỉ có thể là một int.
— Ksempac

Câu trả lời:


119

Có một vấn đề quan trọng và tế nhị mà không ai trong số họ giải quyết trực tiếp. Có hai cách để xem xét kiểu trong C #: kiểu tĩnh và kiểu thời gian chạy .

Loại tĩnh là loại biến trong mã nguồn của bạn. Do đó, nó là một khái niệm thời gian biên dịch. Đây là loại mà bạn thấy trong chú giải công cụ khi di chuột qua một biến hoặc thuộc tính trong môi trường phát triển của mình.

Bạn có thể lấy kiểu tĩnh bằng cách viết phương thức chung của trình trợ giúp để cho phép suy luận kiểu xử lý nó cho bạn:

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

Kiểu thời gian chạy là kiểu của một đối tượng trong bộ nhớ. Do đó, nó là một khái niệm thời gian chạy. Đây là kiểu được trả về bởi GetType()phương thức.

Kiểu thời gian chạy của một đối tượng thường khác với kiểu tĩnh của biến, thuộc tính hoặc phương thức giữ hoặc trả về nó. Ví dụ: bạn có thể có mã như sau:

object o = "Some string";

Kiểu tĩnh của biến là object, nhưng tại thời điểm chạy, kiểu tham chiếu của biến là string. Do đó, dòng tiếp theo sẽ in "System.String" vào bảng điều khiển:

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

Tuy nhiên, nếu bạn di chuột qua biến otrong môi trường phát triển của mình, bạn sẽ thấy loại System.Object(hoặc objecttừ khóa tương đương ). Bạn cũng thấy như vậy bằng cách sử dụng chức năng trợ giúp của chúng tôi từ phía trên:

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

Đối với các biến giá trị gia loại, chẳng hạn như int, double, System.Guid, bạn biết rằng loại thời gian chạy sẽ luôn luôn giống như các loại tĩnh, bởi vì các loại giá trị không thể phục vụ như là lớp cơ sở cho loại hình khác; loại giá trị được đảm bảo là loại có nguồn gốc nhiều nhất trong chuỗi kế thừa của nó. Điều này cũng đúng với các kiểu tham chiếu được niêm phong: nếu kiểu tĩnh là kiểu tham chiếu được niêm phong, giá trị thời gian chạy phải là một phiên bản của kiểu đó hoặc null.

Ngược lại, nếu kiểu tĩnh của biến là kiểu trừu tượng thì được đảm bảo rằng kiểu tĩnh và kiểu thời gian chạy sẽ khác nhau.

Để minh họa điều đó trong mã:

// 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
vì vậy variable.getType()trả về kiểu thời gian chạy (kiểu bên phải), nhưng trả về kiểu tĩnh (kiểu bên trái của một biến) là gì?
— barlop

@barlop được biết đến tại thời điểm biên dịch. Bạn có thể sử dụng typeofđể lấy một đối tượng kiểu trong thời gian chạy cho kiểu tĩnh.
— phoog

vâng, tôi biết kiểu tĩnh = kiểu thời gian biên dịch và kiểu thời gian chạy = kiểu động. Mặc dù đang nhận loại biến 'a', bạn không thể làm được typeof(a) nếu bạn làm typeof(int)vậy sẽ trả về int, nhưng không kiểm tra biến 'a' và hiển thị cho bạn loại 'a' .. Bạn có thể nói rằng bạn không cần hiển thị kiểu tĩnh của 'a', có thể là như vậy, nhưng thực tế là nó không hiển thị nó. Vì vậy, tôi không thấy việc sử dụng typeof ở đây hữu ích như thế nào.
— barlop

4
@barlop bạn có thể làm điều này để cho suy luận kiểu chăm sóc nó cho bạn:Type GetStaticType < T > (T x) { return typeof(T); }
— phoog

1
@Jaquarh như bạn có thể nhận thấy, switchhiện hỗ trợ khớp mẫu để kiểm tra kiểu (kiểu thời gian chạy, không phải tĩnh). Thay vì bật giá trị được trả về từ GetType (), bạn bật trực tiếp biến.
— phoog

17

Nó rất đơn giản

variable.GetType().Name

nó sẽ trả về kiểu dữ liệu của biến của bạn


16

Nói chung, bạn sẽ hầu như không cần thực hiện so sánh kiểu trừ khi bạn đang làm gì đó với sự phản chiếu hoặc giao diện. Tuy nhiên:

Nếu bạn biết loại bạn muốn so sánh với nó, hãy sử dụng các toán tử ishoặc as:

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

Các asnhà điều hành thực hiện một dàn diễn viên mà trả về NULL nếu nó không thành công chứ không phải là một ngoại lệ:

TypeIKnow typed = unknownObject as TypeIKnow;

Nếu bạn không biết kiểu và chỉ muốn thông tin kiểu thời gian chạy, hãy sử dụng phương thức .GetType ():

Type typeInformation = unknownObject.GetType();

Trong các phiên bản C # mới hơn, bạn có thể sử dụng istoán tử để khai báo một biến mà không cần sử dụng as:

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

Trước đây, bạn sẽ phải làm điều này:

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

4

Chỉ cần giữ con trỏ qua thành viên mà bạn quan tâm và xem chú giải công cụ - nó sẽ hiển thị loại memeber:

nhập mô tả hình ảnh ở đây



3

Một tùy chọn sẽ là sử dụng phương pháp mở rộng trình trợ giúp như sau:

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() phương pháp

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

0

kiểm tra một trong những cách đơn giản để làm điều này

// 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.");
        }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.