Type.GetType (tên không gian tên miền.abClassName ') trả về null


216

Mã này:

Type.GetType("namespace.a.b.ClassName")

trả lại null.

và tôi có trong các ứng dụng:

using namespace.a.b;

Cập nhật:

Kiểu tồn tại, nó nằm trong một thư viện lớp khác và tôi cần lấy nó theo tên chuỗi.


Xem stackoverflow.com/questions/441680/ này để biết thông tin về cách lấy tên đủ điều kiện lắp ráp.
Polyfun

Câu trả lời:


244

Type.GetType("namespace.qualified.TypeName") chỉ hoạt động khi loại được tìm thấy trong mscorlib.dll hoặc lắp ráp hiện đang thực thi.

Nếu cả hai điều này đều không đúng, bạn sẽ cần một tên đủ điều kiện lắp ráp :

Type.GetType("namespace.qualified.TypeName, Assembly.Name")

3
kiểu tồn tại, nó nằm trong một thư viện lớp khác và tôi cần lấy nó theo tên chuỗi
Omu

25
Thay vì sử dụng tên đủ điều kiện lắp ráp, bạn có thể tải lắp ráp theo tên - Assembly a = Assembly.Load("SomeLibrary");- và sau đó tải loại theo tên từ cụm - Type t = a.GetType("namespace.a.b.ClassName");.
Kenny Evitt

6
Có lẽ bạn có thể muốn typeof(SomeTypeInThatAssembly).Assembly.GetTypes().Where((t) => t.FullName == youFullName);tiết kiệm một số rắc rối, cuối cùng
Felype

Phản hồi của Felype là người duy nhất tôi có thể làm việc.
Rudy Scoggins

Thêm .FirstOrDefault () vào bình luận @Felype
Leandro

173

Bạn cũng có thể lấy loại không có tên đủ điều kiện lắp ráp nhưng với tên dll cũng có, ví dụ:

Type myClassType = Type.GetType("TypeName,DllName");

Tôi đã có tình huống tương tự và nó đã làm việc cho tôi. Tôi cần một đối tượng thuộc loại "DataModel.QueueObject" và có một tham chiếu đến "DataModel" vì vậy tôi có loại như sau:

Type type = Type.GetType("DataModel.QueueObject,DataModel");

Chuỗi thứ hai sau dấu phẩy là tên tham chiếu (tên dll).


2
Đây là một 'mẹo' hay một phương pháp thực tế? Tôi không thể tìm thấy điều này trong tài liệu -_-. Nhân tiện, nó kết thúc 1 tuần đau khổ của tôi! cảm ơn
DnR

1
Đây là một giải pháp sạch hơn nhiều, tôi rất muốn xem liệu có bất kỳ cạm bẫy nào vì điều này không.
cossacksman

4
Biểu mẫu được sử dụng trong câu trả lời này cũng là một tên loại đủ điều kiện theo ngữ pháp MSDN (vì vậy nó không phải là một mẹo ). Biểu mẫu là NamespaceTypeName, AssemblyNameSpecnơi AssemblyNameSpecđịnh danh của lắp ráp mà không có thuộc tính nào. Mặc dù câu trả lời này là về cơ bản giống như chấp nhận tôi cho rằng một số người thích điều này vì nó không đi với một số trong những "tiếng ồn" mà các thuộc tính lắp ráp giới thiệu (ví dụ Version, Culture PublicKeyToken). May mắn thay, các thuộc tính là tùy chọn .
Martin Liversage

Đối với các loại lồng nhau, bạn có thể cần phải làm một cái gì đó nhưAtlasKernelBusinessModel.AtlasConstants+ClaimCoverage+Status,AtlasKernelBusinessModel
chập chững

Cảm ơn, nó hoạt động cho thư mục App_Code. Ví dụ: Type.GetType ("TypeName, App_Code");
Burak Koray Balcı

79

thử sử dụng phương pháp này

 public static Type GetType(string typeName)
        {
            var type = Type.GetType(typeName);
            if (type != null) return type;
            foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
            {
                type = a.GetType(typeName);
                if (type != null)
                    return type;
            }
            return null ;
        }

Đây là những gì thực sự làm việc cho tôi. Tuy nhiên, tôi đã phải điều chỉnh bằng cách thêm một chuỗi cắt con trước vòng lặp foreach, bởi vì tôi đã chuyển vào một tên đủ điều kiện lắp ráp và Association.GetType () chỉ hoạt động nếu bạn loại trừ thông tin lắp ráp.
Colin

Điều này có vẻ tuyệt vời, nhưng những gì về generic sử dụng các loại lắp ráp khác?
Demetris Leptos

Không hoạt động cho UWP vì AppDomainkhông được hỗ trợ. Không chắc chắn về bất kỳ lựa chọn thay thế.
James M

25
Dictionary<string, Type> typeCache;
...
public static bool TryFindType(string typeName, out Type t) {
    lock (typeCache) {
        if (!typeCache.TryGetValue(typeName, out t)) {
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
                t = a.GetType(typeName);
                if (t != null)
                    break;
            }
            typeCache[typeName] = t; // perhaps null
        }
    }
    return t != null;
}

1
Điều này có vẻ tuyệt vời, nhưng những gì về generic sử dụng các loại lắp ráp khác?
Demetris Leptos

1
@DemetrisLeptos (Tôi biết nhận xét đã cũ - nhưng những người khác vẫn có thể quan tâm): use int index = typeName.IndexOf ('`'); if (index> 0) {typeName = _typeName.Sub chuỗi (0, index + 2); } Lưu ý rằng Tloại chung được loại bỏ.
Bernhard Hiller

25

Nếu tập hợp là một phần của quá trình xây dựng ứng dụng ASP.NET, bạn có thể sử dụng lớp BuildManager:

using System.Web.Compilation
...
BuildManager.GetType(typeName, false);

1
Đây là một câu trả lời tuyệt vời và nên được đưa lên cao hơn trên trang. Hoạt động như một bùa mê và rất đơn giản so với cách cũ để có được tên loại đủ điều kiện của hội đồng.
Graham

Điều này thật đơn giản và đáng chú ý, bạn có thể giúp tôi tối ưu hóa hiệu suất của các đối tượng phản chiếu không?
Alok

15

nếu lớp của bạn không có trong assambly hiện tại, bạn phải cung cấp QualName và mã này cho biết làm thế nào để có được tên của lớp

string qualifiedName = typeof(YourClass).AssemblyQualifiedName;

và sau đó bạn có thể nhận được loại với QualName

Type elementType = Type.GetType(qualifiedName);

8

Nếu đó là Loại lồng nhau, bạn có thể quên chuyển đổi a. đến một +

Bất kể, typeof( T).FullNamesẽ cho bạn biết những gì bạn nên nói

EDIT: BTW các cách sử dụng (như tôi chắc chắn bạn biết) chỉ là các chỉ thị cho trình biên dịch tại thời điểm biên dịch và do đó không thể có bất kỳ tác động nào đến thành công của lệnh gọi API. (Nếu bạn có tài liệu tham khảo dự án hoặc lắp ráp, điều đó có khả năng có ảnh hưởng - do đó thông tin không vô dụng, nó chỉ cần một số bộ lọc ...)


Ôi trời! Bạn có biết cú pháp "+" - được giải thích ở đâu không?
Người bảo vệ một

1
Người bảo vệ Tôi đã học được nó từ amazon.com/Essential-NET-Common-L Language-R.78 / dp / 0201734117 IIRC, nhưng đó là một chút ngày. Tôi có thể giới thiệu amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/NH như một cuốn sách hữu ích cho tất cả các nhà phát triển .NET + bao gồm điều này không? Điểm mấu chốt là đối với các Loại, CLR chỉ có không gian tên và tên - một loại lồng nhau không thể truy cập trực tiếp. Do đó, một ngôn ngữ, nếu nó có khái niệm kiểu lồng nhau sẽ thực hiện những gì nó cần (mặc dù nói chung hầu hết các lang đều sử dụng +dấu phân cách)
Ruben Bartelink

6

Tôi đang mở các điều khiển người dùng tùy thuộc vào những gì người dùng kiểm soát mà người dùng có quyền truy cập được chỉ định trong cơ sở dữ liệu. Vì vậy, tôi đã sử dụng phương thức này để lấy TypeName ...

Dim strType As String = GetType(Namespace.ClassName).AssemblyQualifiedName.ToString
Dim obj As UserControl = Activator.CreateInstance(Type.GetType(strType))

Vì vậy, bây giờ người ta có thể sử dụng giá trị được trả về trong strType để tạo một thể hiện của đối tượng đó.


mở lại một chủ đề cũ sử thi ... xin chúc mừng. Tuy nhiên tôi phải đánh giá thấp câu trả lời của bạn vì TO thực sự biết Typename và muốn lấy loại từ nó. Btw.: Bạn tham chiếu phương thức nào bởi <c> GetType (Namespace.ClassName) </ c>, nếu Type.GetType, nó sẽ chỉ hoạt động trên các loại trong hội đồng thực thi hiện tại hoặc mscorlib của bạn, nhưng với tư cách là không những điều kiện này được áp dụng.
HimBromBeere

2
@HimBromBeere Cảm ơn bạn đã bỏ phiếu. Chính những người như bạn đã hạ bệ tôi để đăng những phát hiện của tôi. Tôi vẫn đang học phát triển và tôi chỉ đang cố gắng giúp đỡ người khác. Và bây giờ bạn mong tôi trả lời câu hỏi của bạn? Nhân tiện, tôi đã trả lời chính xác câu hỏi. Lớp mà tôi đang tạo một thể hiện cư trú trong một dự án khác và người ta phải sử dụng một tên hội đồng vì điều đó. Vì vậy, vui lòng đọc phần còn lại của các ý kiến ​​trước khi bỏ phiếu. "Kiểu tồn tại, nó nằm trong một thư viện lớp khác và tôi cần lấy nó theo tên chuỗi - Omu"
Stephan

6

Khi tôi chỉ có tên lớp, tôi sử dụng cái này:

Type obj = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).Where(t => String.Equals(t.Name, _viewModelName, StringComparison.Ordinal)).First();

5

Type.GetType (Chuỗi) cần Type.AssuggingQualifiedName, bạn nên sử dụng Association.CreateQualifiedName (String, String) .

string typeName = "MyNamespace.MyClass"; // Type.FullName
string assemblyName = "MyAssemblyName"; // MyAssembly.FullName or MyAssembly.GetName().Name
string assemblyQualifiedName = Assembly.CreateQualifiedName(assemblyName , typeName);
Type myClassType = Type.GetType(assemblyQualifiedName);

Phiên bản, Văn hóa và PublicKeyToken không bắt buộc vì assemblyNameđó là lý do tại sao bạn có thể sử dụng MyAssugging.GetName (). Name.

Giới thiệu về Type.GetType (Chuỗi) :

Nếu loại nằm trong hội đồng hiện đang thực thi hoặc trong Mscorlib.dll, thì việc cung cấp tên loại đủ điều kiện theo không gian tên của nó là đủ.


4

Nếu lắp ráp được tham chiếu và Class hiển thị:

typeof(namespace.a.b.ClassName)

GetType trả về null vì không tìm thấy loại, với typeof, trình biên dịch có thể giúp bạn tìm ra lỗi.


kiểu tồn tại, nó nằm trong một thư viện lớp khác và tôi cần lấy nó theo tên chuỗi
Omu

4

Hãy thử sử dụng tên loại đầy đủ bao gồm thông tin lắp ráp, ví dụ:

string typeName = @"MyCompany.MyApp.MyDomain.MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
Type myClassType = Type.GetType(typeName);

Tôi đã gặp tình huống tương tự khi tôi chỉ sử dụng tên namesspace. Classname để lấy loại lớp trong một cụm khác và nó sẽ không hoạt động. Chỉ hoạt động khi tôi bao gồm thông tin lắp ráp trong chuỗi loại của tôi như được hiển thị ở trên.


3

Đảm bảo rằng dấu phẩy trực tiếp sau tên đủ điều kiện

typeof(namespace.a.b.ClassName, AssemblyName)

Vì điều này sẽ không làm việc

typeof(namespace.a.b.ClassName ,AssemblyName)

Tôi đã bối rối trong một vài ngày về điều này


2

Đối với tôi, "+" là chìa khóa! Đây là lớp học của tôi (nó là một lớp lồng nhau):

namespace PortalServices
{
public class PortalManagement : WebService
{
    public class Merchant
    {}
}
}

và dòng mã này đã hoạt động:

Type type = Type.GetType("PortalServices.PortalManagement+Merchant");

1

Giải pháp này ở trên có vẻ là tốt nhất đối với tôi, nhưng nó không hiệu quả với tôi, vì vậy tôi đã làm như sau:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(HttpContext.Current.Server.MapPath("~\\Bin\\AnotherAssembly.dll"));
string typeAssemblyQualifiedName = string.Join(", ", "MyNamespace.MyType", assemblyName.FullName);

Type myType = Type.GetType(typeAssemblyQualifiedName);

Điều kiện tiên quyết là bạn biết đường dẫn của lắp ráp. Trong trường hợp của tôi, tôi biết điều đó bởi vì đây là một hội đồng được xây dựng từ một dự án nội bộ khác và nó được bao gồm trong thư mục bin của dự án của chúng tôi.

Trong trường hợp có vấn đề tôi đang sử dụng Visual Studio 2013, .NET mục tiêu của tôi là 4.0. Đây là một dự án ASP.NET, vì vậy tôi nhận được đường dẫn tuyệt đối thông qua HttpContext. Tuy nhiên, đường dẫn tuyệt đối không phải là một yêu cầu vì có vẻ như từ MSDN trên AssociationQualifiedNames


0

Tôi đã lừa dối. Vì các loại tôi muốn tạo (theo tên) đều nằm trong một dll tôi điều khiển, tôi chỉ cần đặt một phương thức tĩnh trong dll trong cụm có một tên đơn giản và gọi type.GetType từ ngữ cảnh đó và trả về kết quả .

Mục đích ban đầu là để loại có thể được chỉ định theo tên trong dữ liệu cấu hình. Kể từ khi tôi thay đổi mã để người dùng chỉ định một định dạng cần xử lý. Các lớp xử lý định dạng thực hiện một giao diện xác định xem loại có thể phân tích định dạng được chỉ định hay không. Sau đó tôi sử dụng sự phản chiếu để tìm các kiểu thực hiện giao diện và tìm một kiểu xử lý định dạng. Vì vậy, bây giờ cấu hình chỉ định một tên định dạng, không phải là một loại cụ thể. Mã phản chiếu có thể nhìn vào các dll liền kề và tải, vì vậy tôi có kiến ​​trúc trình cắm thêm của một người nghèo.


Xin chào, tôi đã bị từ chối do nhầm lẫn, vui lòng chỉnh sửa câu trả lời của bạn để tôi có thể hoàn tác nó.
coloboxp
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 cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.