2009-09-08 2 views
12

Tôi đang cố gắng để có được một đối tượng Loại từ loại tên đầy đủ tôi đang làm folowing:Tạo C# Loại từ tên đầy đủ

Assembly asm = Assembly.GetEntryAssembly(); 
string toNativeTypeName="any type full name"; 
Type t = asm.GetType(toNativeTypeName); 

tôi nhận được null, tại sao?

lắp ráp được thực thi của tôi (.net thực thi) và tên loại là: System.Xml.XmlNode

+0

Hiển thị cho chúng tôi ý nghĩa của bạn bằng tên đầy đủ? – AnthonyWJones

+0

assembly là tệp thực thi của tôi (.net executable) và tên kiểu là: System.Xml.XmlNode –

+0

System.Xml.XmlNode sẽ không tồn tại trong assembly của bạn vì vậy bạn nên sử dụng Type.GetType inestead của Assembly.GetType. –

Trả lời

27

Vâng, nếu đó thực sự là tên đầy đủ của loại (tức là bao gồm cả không gian tên) và nó trong lắp ráp đó, thì nó sẽ hoạt động. Bạn có thể đưa ra một ví dụ mà nó không? Vì bạn đang sử dụng Assembly.GetType thay vì Type.GetType bạn không nên bao gồm tên lắp ráp trong tên loại.

Lưu ý rằng tên cho loại chung không phải là những gì bạn có thể mong đợi. Ví dụ: bạn sẽ sử dụng:

assembly.GetType("System.Collections.Generic.List`1"); 

để nhận loại danh sách chung, sau đó sử dụng Type.MakeGenericType để cung cấp đối số loại.

Tất nhiên, điều đó chỉ có liên quan khi loại đó là chung chung. Nếu đó không phải là vấn đề, tôi sẽ kiểm tra kỹ xem loại thực sự có nằm trong assembly của bạn hay không.

EDIT: Oh, và nhận thức được rằng các loại lồng nhau sẽ là "container + lồng nhau" hơn là "Container.Nested" nếu đó là có liên quan ...

+0

assembly là tệp thực thi của tôi (.net executable) và tên kiểu là: System.Xml.XmlNode –

+4

Sau đó, đó là vấn đề: System.Xml.XmlNode không phải là một kiểu trong assembly của bạn, đúng không? Bạn sẽ cần sử dụng đúng assembly hoặc gọi Type.GetType với thông tin assembly đầy đủ. –

+0

+1 Rất nhiều thông tin tốt ở đây. –

4

tên loại của bạn có lẽ là sai lầm nhất. Nếu bạn tạo tham chiếu đến loại mã và sau đó kiểm tra thuộc tính Type.FullName của bạn, bạn sẽ thấy tên của loại sẽ trông như thế nào.

Ngoài ra, bạn có thể thử phương thức Type.GetType và xem phương thức trả về. Có lẽ loại của bạn không có trong hội đồng đó?

Chỉnh sửa: Hóa ra tôi đã sai khi sử dụng thuộc tính Type.FullName. Nếu bạn sử dụng thuộc tính Type.AssemblyQualifiedName, bạn sẽ nhận được tên đầy đủ có thể được sử dụng bởi Type.GetType.

Đối System.Xml.XmlNode bạn có được những tên sau: System.Xml.XmlElement, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

6

lý do tại sao bạn đang định lắp ráp để sử dụng được gõ !, bạn cũng cần phải đặt namespace

string toNativeTypeName = "System.Int32"; 
Type t = Type.GetType(toNativeTypeName); 
MessageBox.Show(t.FullName); 
+3

Nếu bạn biết rằng kiểu * là * trong assembly nhập, sau đó sử dụng Assembly.GetType với tên bao gồm namespace nhưng * not * tên assembly có thể dễ dàng hơn nhiều so với bao gồm tên assembly đầy đủ bao gồm version ... –

+0

Điều này đã giúp tôi. Tôi đã cố gắng kéo các tin nhắn được sắp xếp theo thứ tự ra khỏi hàng đợi. Tôi đã thử nghiệm với System.String và không tìm thấy nó trong khi lặp qua tất cả các hội đồng từ miền hiện tại. Khi tôi thay đổi để sử dụng Type.GetType, nó chỉ hoạt động. Cảm ơn vì tiền hỗ trợ. – fizch

3

Tôi đã xem qua chủ đề này và nhận thấy rằng câu hỏi ban đầu chưa được trả lời. Tôi có thể sai, nhưng trong việc đọc câu hỏi tôi nghĩ ý định của tác giả là có thể đơn giản nhận được một loại từ một hội đồng được tham chiếu hoặc một phần của ứng dụng của bạn.

Đây là những gì tôi đã làm để giải quyết vấn đề đó.

public static Type GetTypeFromFullName(string fullClassName) 
{ 
    AssemblyPartCollection parts = Deployment.Current.Parts; 

    foreach (var part in parts) 
    { 
     Uri resUri = new Uri(part.Source, UriKind.Relative); 
     Stream resStream = Application.GetResourceStream(resUri).Stream; 
     Assembly resAssembly = part.Load(resStream); 
     Type tryType = resAssembly.GetType(fullClassName, false); 
     if (tryType != null) 
      return tryType; 
    } 

    return null; 
} 
8

Xem gợi ý của tôi dưới đây, chỉ lặp namespace kinh doanh cho tốc độ

private static Type GetBusinessEntityType(string typeName) 
{ 
    Debug.Assert(typeName != null); 

    List<System.Reflection.Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies() 
     .Where(a => a.FullName.StartsWith("AF.BusinessEntities")).ToList(); 

    foreach (var assembly in assemblies) 
    { 
     Type t = assembly.GetType(typeName, false); 
     if (t != null) 
      return t; 
    } 
    throw new ArgumentException(
     "Type " + typeName + " doesn't exist in the current app domain"); 
} 

Dưới đây là một cách khác để làm điều đó:

Type t = System.Web.Compilation.BuildManager.GetType("the.type", true, false); 

Sử dụng phản xạ để xem làm thế nào nó được thực hiện, ít nhất là cho vui vẻ :)

+1

'System.Web.Compilation.BuildManager' đã làm điều đó cho tôi, một người khác tôi đã không làm cho nó hoạt động cho một Enum:' NLibrary + Modules' – Niels