2010-03-02 23 views
19

Ở nhiều nơi, tôi gặp phải các tên loại có chất lượng một phần của biểu mẫu FullTypeName, AssemblyName, ví dụ như chỉ Type.AssemblyQualifiedName mà không có phiên bản vòng loại, văn hóa và vòng loại publicKeyToken.Cách Type.GetType hoạt động khi được đặt tên loại có một phần đủ điều kiện?

Câu hỏi của tôi là cách một người có thể chuyển đổi nó thành Type tương ứng trong nỗ lực tối thiểu? Tôi nghĩ rằng Type.GetType hiện công việc, nhưng than ôi, nó không. Các mã sau đây, ví dụ, trả null:

Type.GetType("System.Net.Sockets.SocketException, System"); 

Tất nhiên, nếu tôi ghi rõ tên đầy đủ nó không làm việc:

Type.GetType("System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 

Thanks a lot.

+0

Bạn có loại lúc biên dịch không? Nếu vậy tại sao không sử dụng typeof () .FullName, et. al? Nếu bạn có loại khi chạy, bạn có thể sử dụng .GetType(). FullName et. al. Hoặc tôi có thiếu yêu cầu cụ thể không? Tôi nhận được rằng bạn chỉ muốn chỉ định một phần tên, nhưng thats thực sự nhiều hơn cho bộ nạp hơn là cho hệ thống kiểu. FQNs là để giải quyết các vấn đề tham khảo cho các dịp hiếm hoi xảy ra xung đột tên, điều này là thường xuyên hơn trong các hội đồng người dùng hơn trong các hội đồng BCL. – GrayWizardx

+1

Tôi hoàn toàn nhận thức được typeof() hoặc Type.FullName. Loại đối tượng được đọc từ tệp cấu hình, đó là lý do tôi sử dụng Type.GetType. Và đây là lý do tại sao tôi rất quan tâm đến việc tìm hiểu cách thức hoạt động của một số loại tên đủ điều kiện. – mark

Trả lời

8

Nếu tệp DLL của nó chưa được tải vào miền ứng dụng (ví dụ: bạn đã sử dụng nó), bạn cần đường dẫn đầy đủ như thế này, nếu nó đã được tải, nó có thể tìm thấy nó với phiên bản ngắn hơn.

Để trả lời câu hỏi của bạn: phiên bản thứ hai luôn hoạt động, hãy gắn bó với nó và bạn có một cách để lo lắng.

+1

Tôi không nghĩ rằng việc lắp ráp đã được tải hay chưa - phiên bản ngắn sẽ không hoạt động. Tên đủ điều kiện không gian tên sẽ hoạt động nếu loại đó nằm trong hội đồng hiện đang thực thi hoặc trong mscorlib. Lời giải thích đầy đủ hơn bên dưới. – lesscode

2

Mã làm việc với các hình thức ngắn gọn là:

Assembly a = Assembly.LoadWithPartialName(assemblyName); 
    Type t = a.GetType(typeName); 

nhưng LoadWithPartialName bị phản đối, vì vậy tôi đoán bạn nên gắn bó với dạng dài.

29

Nếu lắp ráp đã được tải trong lĩnh vực hiện tại thì mã dưới đây thường hoạt động:

public static Type GetTypeEx(string fullTypeName) 
{ 
    return Type.GetType(fullTypeName) ?? 
      AppDomain.CurrentDomain.GetAssemblies() 
        .Select(a => a.GetType(fullTypeName)) 
        .FirstOrDefault(t => t != null); 
} 

Bạn có thể sử dụng nó như vậy:

Type t = GetTypeEx("System.Net.Sockets.SocketException"); 
+1

Cảm ơn rất nhiều vì câu trả lời này! Đó là chính xác những gì tôi đang tìm kiếm - tốt hơn nhiều so với câu trả lời "được chấp nhận". –

+2

Chỉ cần nhớ rằng điều này có thể rất chậm, vì vậy đừng quên cache .. – nawfal

2

Sau khi vừa trải qua một vấn đề tương tự với một số mã cũ, tôi không nghĩ rằng câu lệnh đầu tiên trong câu trả lời được chấp nhận là chính xác. Việc lắp ráp có được tải hay không không quan trọng.

Theo tài liệu, Type.GetType(string) yêu cầu AssemblyQualifiedName, trừ khi loại được đề cập trong hội đồng hiện đang thực thi hoặc trong mscorlib, trong trường hợp đó tên loại đủ điều kiện không gian tên là tất cả bắt buộc.

Lưu ý rằng AssemblyQualifiedName bao gồm tên hiển thị đầy đủ của hội đồng loại (với phiên bản, văn hóa và mã thông báo khóa công khai).

Phiên bản ngắn sẽ không hoạt động trừ khi bạn chặn tải loại không thành công với tùy chỉnh AssemblyResolver (thực tế là trường hợp xảy ra sự cố của tôi, che giấu một vấn đề khác).

0

True, Type.GetType (string) không yêu cầu AssemblyQualifiedName.Điều này có thể dưới nhiều hình thức:

MyNS.MyType, MyAssembly, Version=x.x.x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 

Sau đây cũng là AssemblyQualifiedNames hợp lệ:

MyNS.MyType, MyAssembly, Version=x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly 

Đối với một hội đồng được ký kết, yêu cầu tối thiểu cho một FullyQualifiedAssemblyName là:

MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 

Đối với một hội đồng chưa ký, yêu cầu tối thiểu đối với FullyQualifiedAssemblyName là:

MyNS.MyType, MyAssembly 

Không cần tất cả thao tác "vẫy tay" đang diễn ra trong đoạn mã mà người khác đã cung cấp. Đảm bảo rằng tên loại của bạn được thiết lập đúng cách và bạn có thể truy cập các loại của bạn (và nạp linh hoạt) với độ linh hoạt cao. Tôi làm điều này thường xuyên.

Trong ví dụ OP bằng cách sử dụng:

Type.GetType("System.Net.Sockets.SocketException, System") 

Lý do cho sự thất bại là sự vắng mặt của PublicKeyToken. Tất cả các hội đồng .Net FW đều được ký và do đó yêu cầu PublicKeyToken giải quyết tên Assembly. Công việc sau đây sẽ hoạt động:

Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089") 
Các vấn đề liên quan