Type.GetType(“ namespace.abClassName”)はnullを返します


216

このコード:

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

を返しますnull

そして私は使用しています:

using namespace.a.b;

更新:

型が存在し、別のクラスライブラリにあり、文字列名で取得する必要があります。


アセンブリ修飾名を取得する方法については、このstackoverflow.com/questions/441680/…を参照してください。
Polyfun 2009

回答:


244

Type.GetType("namespace.qualified.TypeName") タイプがmscorlib.dllまたは現在実行中のアセンブリで見つかった場合にのみ機能します。

これらのどちらも当てはまらない場合は、アセンブリ修飾名が必要です。

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

3
タイプが存在し、別のクラスライブラリにあり、文字列名で取得する必要がある
Omu

25
アセンブリ修飾名を使用する代わりに、名前でアセンブリを読み込み、– Assembly a = Assembly.Load("SomeLibrary");アセンブリから型を名前で読み込むことができますType t = a.GetType("namespace.a.b.ClassName");
ケニーエビット

6
多分あなたはあなたが好きtypeof(SomeTypeInThatAssembly).Assembly.GetTypes().Where((t) => t.FullName == youFullName);かもしれないいくつかの手間を最終的に救うかもしれません
Felype

フェリペの反応は私が働くことができる唯一のものでした。
Rudy Scoggins、2018年

@Felypeコメントに.FirstOrDefault()を追加
Leandro

173

アセンブリ修飾名なしでDLL名を使用してタイプを取得することもできます。次に例を示します。

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

私も同じ状況で、うまくいきました。「DataModel.QueueObject」タイプのオブジェクトが必要であり、「DataModel」への参照があったため、次のようにタイプを取得しました。

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

コンマの後の2番目のストリングは、参照名(dll名)です。


2
これは「トリック」または実際の方法ですか?ドキュメントにこれが見つかりません-_-。ちなみに、1週間は苦しんでしまいます!ありがとう
DnR 14

1
これはよりクリーンなソリューションです。このために落とし穴があるかどうかを確認したいと思います。
cossacksman

4
この回答で使用されるフォームは、MSDN文法による完全修飾型名でもあります(そのため、トリックではありません)。フォームはNamespaceTypeName, AssemblyNameSpecAssemblyNameSpecプロパティのないアセンブリの識別子です。この回答は基本的に受け入れられたものと同じですが、アセンブリプロパティがもたらす「ノイズ」の一部を排除するため(たとえばVersionCulture PublicKeyToken)、一部の人々はこれを好むと思います。幸い、プロパティはオプションです
Martin Liversage、2016年

ネストされた型の場合、次のような操作が必要になる場合がありますAtlasKernelBusinessModel.AtlasConstants+ClaimCoverage+Status,AtlasKernelBusinessModel
toddmo

おかげで、それはApp_Codeフォルダーで機能します。例:Type.GetType( "TypeName、App_Code");
Burak KorayBalcı2017

79

この方法を試してください

 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 ;
        }

これは実際に私のために働いたものです。ただし、アセンブリ修飾名を渡したため、foreachループの前に部分文字列トリムを追加して微調整する必要があり、Assembly.GetType()は、アセンブリ情報を除外した場合にのみ機能します。
コリン、

これは素晴らしいように見えますが、他のアセンブリタイプを使用するジェネリックスについてはどうですか
デメトリスレプトス2016年

AppDomainサポートされていないため、UWPでは機能しません。代替案がわからない。
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
これは素晴らしいように見えますが、他のアセンブリタイプを使用するジェネリックスについてはどうですか
デメトリスレプトス2016年

1
@DemetrisLeptos(コメントが古いことは承知していますが、他の人も興味があるかもしれません):int index = typeName.IndexOf( '`');を使用します。if(index> 0){typeName = _typeName.Substring(0、index + 2); Tジェネリック型のは取り除かれていることに注意してください。
Bernhard Hiller、

25

アセンブリがASP.NETアプリケーションのビルドの一部である場合、BuildManagerクラスを使用できます。

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

1
これは素晴らしい答えであり、ページの上の方にあるはずです。チャームのように機能し、アセンブリの修飾された型名を取得する従来の方法に比べて非常に単純です。
グラハム

これは驚くほどシンプルで見つけやすいですが、反射オブジェクトのパフォーマンスの最適化を手伝ってくれませんか?
Alok、2018

15

クラスが現在のアセンブリにない場合は、qualifiedNameを指定する必要があります。このコードは、クラスの修飾名を取得する方法を示しています

string qualifiedName = typeof(YourClass).AssemblyQualifiedName;

そして、あなたはqualifiedNameでタイプを得ることができます

Type elementType = Type.GetType(qualifiedName);

8

ネストされたタイプの場合、の変換を忘れている可能性があります。+に

とにかく、typeof( T).FullNameあなたが言っているべきことを教えてくれます

編集:ところで、使用法(ご存じのとおり)は、コンパイル時のコンパイラに対するディレクティブにすぎないため、API呼び出しの成功に影響を与えることはできません。(プロジェクトまたはアセンブリ参照があった場合、それは潜在的に影響を及ぼした可能性があります-したがって、情報は役に立たないので、フィルタリングが必要です...)


あら!この「+」構文がどこで説明されているか知っていますか?
プロテクター1

1
Protectorone amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117 IIRC からそれを学びましたが、少し日付が遅れています。amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/…をすべての.NET開発者にとって間違いなく有用な本として推奨できますか?結論として、タイプの場合、CLRには名前空間と名前しかありません。ネストされたタイプは直接アドレス指定できません。したがって、ネストされた型の概念を持つ言語は、必要なことを実行できます(一般に、ほとんどの言語では+区切り記号が使用されます)
Ruben Bartelink

6

ユーザーがデータベースで指定されたアクセス権を持つユーザーコントロールに応じて、ユーザーコントロールを開いています。したがって、このメソッドを使用してTypeNameを取得しました...

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

そのため、strTypeで返された値を使用して、そのオブジェクトのインスタンスを作成できます。


昔ながらのトピックを再開しました...おめでとうございます。ただし、TOは実際にTypenameを認識しており、Typenameからタイプを取得する必要があるため、私はあなたの回答に反対票を投じる必要があります。Btw .: <c> GetType(Namespace.ClassName)</ c>でどのメソッドを参照しますか?Type.GetTypeは、現在実行中のアセンブリまたはmscorlib内にある型でのみ機能しますが、TOはありませんこれらの条件の適用されます。
HimBromBeere 2014年

2
@HimBromBeere反対票をありがとう。私の発見を投稿するように私をやる気にさせるのはあなたのような人々です。私はまだ開発を学んでおり、ただ他人を助けようとしています。そして今、あなたは私があなたの質問に答えることを期待していますか?ちなみに、私は質問に正しく答えました。私がインスタンスを作成していたクラスは別のプロジェクトにあり、そのためAssemblyQualifiedの名前を使用する必要があります。ですから、反対票を投じる前に残りのコメントを読んでください。"型が存在し、別のクラスライブラリにあり、文字列名で取得する必要があります–
ステファン

6

私がクラス名しか持っていないとき、私はこれを使います:

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

5

以下のようType.GetType(String)を必要Type.AssemblyQualifiedNameあなたが使用する必要がありますAssembly.CreateQualifiedName(文字列、文字列)

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);

assemblyNameMyAssembly.GetName()。Nameを使用できるのは、Version、Culture、PublicKeyTokenが必要ないためです。

Type.GetType(String)について:

タイプが現在実行中のアセンブリまたはMscorlib.dllにある場合は、その名前空間で修飾されたタイプ名を指定するだけで十分です。


4

アセンブリが参照され、クラスが表示される場合:

typeof(namespace.a.b.ClassName)

タイプが見つからないため、GetTypeはnullを返します。typeofを使用すると、コンパイラーはエラーを見つけるのに役立ちます。


タイプが存在し、別のクラスライブラリにあり、文字列名で取得する必要がある
Omu

4

アセンブリ情報を含む完全な型名を使用してみてください。次に例を示します。

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

namesspace.classnameのみを使用して別のアセンブリのクラスのタイプを取得すると、同じ状況になり、機能しませんでした。上記のように、タイプ文字列にアセンブリ情報を含めた場合にのみ機能しました。


3

コンマが完全修飾名の直後にあることを確認してください

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

これは機能しないので

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

私はこれに数日間悩まされました


2

私にとっては、「+」が鍵でした!これは私のクラスです(ネストされたクラスです):

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

そして、このコード行は機能しました:

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

1

上記のこの解決策は私にとって最良のようですが、私にとってはうまくいかなかったので、次のようにしました:

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

Type myType = Type.GetType(typeAssemblyQualifiedName);

前提条件は、アセンブリのパスを知っていることです。私の場合、これはわかっています。これは、別の内部プロジェクトからビルドされたアセンブリであり、プロジェクトのbinフォルダーに含まれているためです。

私がVisual Studio 2013を使用していることが重要な場合、私のターゲット.NETは4.0です。これはASP.NETプロジェクトなので、を介して絶対パスを取得していHttpContextます。ただし、MSDNのAssemblyQualifiedNamesからのように、絶対パスは必須ではありません


0

私はだまされました。(名前で)作成したい型はすべてdll内にあるので、制御するdllに、単純な名前を取るアセンブリのdllに静的メソッドを配置し、そのコンテキストからtype.GetTypeを呼び出して結果を返します。

元々の目的は、タイプを構成データで名前で指定できるようにすることでした。それ以来、ユーザーが処理するフォーマットを指定するようにコードを変更しました。形式ハンドラクラスは、型が指定された形式を解析できるかどうかを決定するインターフェイスを実装します。次に、リフレクションを使用して、インターフェイスを実装するタイプを見つけ、フォーマットを処理するタイプを見つけます。したがって、構成は特定のタイプではなくフォーマット名を指定します。リフレクションコードは隣接するDLLを調べて読み込むことができるので、私は一種の貧乏人のプラグインアーキテクチャを持っています。


こんにちは、間違って投票しました。元に戻せるように返信を編集してください。
coloboxp
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.