2009-11-23 31 views
7

Tôi muốn có một số hàm sẽ trả về "Cơ sở" nếu biến số Base được chuyển cho nó, "Có nguồn gốc" nếu được khai báo là Derived, v.v. Không phụ thuộc vào kiểu thời gian chạy của một giá trị mà nó được gán cho.Làm thế nào để biết trong mã C# loại biến được khai báo với

+0

Nếu bạn đang sử dụng giải pháp thứ hai của Rô-ma tại sao không chỉ sử dụng 'typeof (T)'? –

+0

@Courtney: Bạn không thể viết 'string s = null; Console.Write (typeof (s)); ', bởi vì s không phải là tên của kiểu hoặc vùng tên. Nó sẽ không biên dịch. –

Trả lời

15

Xem mã bên dưới chẳng hạn. Điều quan trọng là sử dụng Generics, phương pháp mở rộng chỉ được sử dụng cho cú pháp đẹp.

using System; 

static class Program 
{ 
    public static Type GetDeclaredType<T>(this T obj) 
    { 
     return typeof(T); 
    } 

    // Demonstrate how GetDeclaredType works 
    static void Main(string[] args) 
    { 
     ICollection iCollection = new List<string>(); 
     IEnumerable iEnumerable = new List<string>(); 
     IList<string> iList = new List<string>(); 
     List<string> list = null; 

     Type[] types = new Type[]{ 
      iCollection.GetDeclaredType(), 
      iEnumerable.GetDeclaredType(), 
      iList.GetDeclaredType(), 
      list.GetDeclaredType() 
     }; 

     foreach (Type t in types) 
      Console.WriteLine(t.Name); 
    } 
} 

Kết quả:

ICollection 
IEnumerable 
IList`1 
List`1 

EDIT: Bạn cũng có thể tránh sử dụng phương pháp khuyến nông ở đây, vì nó sẽ gây ra nó để xuất hiện trên mỗi IntelliSense danh sách thả xuống. Xem ví dụ khác:

using System; 
using System.Collections; 

static class Program 
{ 
    public static Type GetDeclaredType<T>(T obj) 
    { 
     return typeof(T); 
    } 

    static void Main(string[] args) 
    { 
     ICollection iCollection = new List<string>(); 
     IEnumerable iEnumerable = new List<string>(); 

     Type[] types = new Type[]{ 
       GetDeclaredType(iCollection), 
       GetDeclaredType(iEnumerable) 
     }; 

     foreach (Type t in types) 
      Console.WriteLine(t.Name); 
    } 
} 

cũng tạo ra kết quả chính xác.

+1

+1. Trơn tru! (điền vào giới hạn 15 char) – Heinzi

+0

wow! cảm ơn rất nhiều!!! – Misha

+1

Tôi sẽ sử dụng giải pháp thứ 2 (từ bản chỉnh sửa của bạn), cảm ơn bạn – Misha

2

Chỉ cần recurse trên GetType() cho đến khi bạn nhấn đối tượng.

+1

Vâng, tôi đã làm điều này, nó hoạt động nhưng chậm. – Misha

4

Điều này là không thể nếu không phân tích cú pháp mã được đề cập.

Khi chạy chỉ có hai mẩu thông tin loại có sẵn, các thực tế loại một giá trị (thông qua object.GetType()) và, nếu biến trong câu hỏi là một tham số hoặc lớp/biến dụ FieldType tài sản trên một FieldInfo, PropertyType trên PropertyInfo hoặc ParameterType trên ParameterInfo.

Vì giá trị được chuyển cho bạn có thể đã đến thông qua một số biến trên tuyến đường của nó cho bạn, câu hỏi này thậm chí không được xác định rõ là tôi sợ. Ah, tôi thấy bạn chỉ muốn loại như hiện đang được xác định trong phương pháp, chức năng biểu thức sẽ cung cấp này (câu trả lời của Roman cho thấy một cách gọn gàng để làm điều này) nhưng hãy cẩn thận cố gắng sử dụng này bên ngoài phương pháp ... Trong bản chất bạn đang cho phép suy luận kiểu chung của trình biên dịch suy ra loại được đề cập nhưng điều này có nghĩa là biến được sử dụng là không phải là luôn là biến mà bạn có thể thấy. Thay vào đó, nó có thể là biến số tổng hợp của trình biên dịch, ví dụ:

string x = "x"; 
Console.WriteLine(x.GetDeclaredType()); // string 
Console.WriteLine(((object)x).GetDeclaredType()); // object 

Vì trình biên dịch tổng hợp một biến tạm thời để đặt đối tượng tham chiếu đến x.

+0

+1, btw, thực tế được gọi là loại "cụ thể" ... –

+0

Tôi không quan tâm đến một giá trị, chỉ tên của loại biến được khai báo với ... Cảm ơn anyway, thông tin hữu ích. – Misha

+0

+1 cho cảnh báo của bạn –

Các vấn đề liên quan