Nasıl bir isim alanındaki tüm sınıfları C # yansıması ile elde edersiniz?
Nasıl bir isim alanındaki tüm sınıfları C # yansıması ile elde edersiniz?
Yanıtlar:
Aşağıdaki kod namespace
, geçerli derlemede tanımlanan sınıftaki adları yazdırır .
Diğer adamların işaret ettiği gibi, farklı modüller arasında bir ad alanı dağıtılabilir, bu yüzden önce montajların bir listesini almanız gerekir.
string nspace = "...";
var q = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == nspace
select t;
q.ToList().ForEach(t => Console.WriteLine(t.Name));
FlySwat'un dediği gibi, birden fazla montajda aynı ad alanına sahip olabilirsiniz (örneğin System.Collections.Generic
). Zaten yüklü değilse, tüm bu montajları yüklemeniz gerekecektir. Tam bir cevap için:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
Diğer etki alanlarının sınıflarını istemiyorsanız, bu işe yaramalıdır. Tüm alan adlarının bir listesini almak için bu bağlantıyı izleyin .
&& t.Namespace == @namespace
" - kaldırmaya çalıştım hangi ofcause bana tüm .net meclisleri verdi :-)
&& t.Namespace == @namespace
tüm almak sınıfları arasında tüm meclisleri .net de dâhil. GetAssemblies
size tüm montajları GetAssemblies().SelectMany(t => t.GetTypes())
verecek ve tüm montajlardan tüm türleri (sınıflar, yapılar vb.) verecektir.
Assembly.Load(nameof(NameOfMyNamespace))
çalışarak kullanarak bir montajın yüklenmesini zorladığımı buldum .
using System.Reflection;
using System.Collections.Generic;
//...
static List<string> GetClasses(string nameSpace)
{
Assembly asm = Assembly.GetExecutingAssembly();
List<string> namespacelist = new List<string>();
List<string> classlist = new List<string>();
foreach (Type type in asm.GetTypes())
{
if (type.Namespace == nameSpace)
namespacelist.Add(type.Name);
}
foreach (string classname in namespacelist)
classlist.Add(classname);
return classlist;
}
NB: Yukarıdaki kod neler olup bittiğini göstermektedir. Uygulansaydınız, basitleştirilmiş bir sürüm kullanılabilir:
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
//...
static IEnumerable<string> GetClasses(string nameSpace)
{
Assembly asm = Assembly.GetExecutingAssembly();
return asm.GetTypes()
.Where(type => type.Namespace == nameSpace)
.Select(type => type.Name);
}
classlist
üzerinde birinci tekrar asm.GetTypes()
sonucu.
Belirli bir Assembly, NameSpace ve ClassName için:
var assemblyName = "Some.Assembly.Name"
var nameSpace = "Some.Namespace.Name";
var className = "ClassNameFilter";
var asm = Assembly.Load(assemblyName);
var classes = asm.GetTypes().Where(p =>
p.Namespace == nameSpace &&
p.Name.Contains(className)
).ToList();
Not: Proje montajı referans almalıdır
Aşağıda, türlerden birinin başka bir derlemede bir tür alt sınıfının olup olmadığını bulacağınız LoaderException hataları için bir düzeltme verilmiştir:
// Setup event handler to resolve assemblies
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();
// process types here
// method later in the class:
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}
Bu, diğer montajlarda tanımlanan yükleme türlerine yardımcı olacaktır.
Umarım yardımcı olur!
Assembly a
bu olayın tetiklenmesine neden olabilecek normal işlemleri temsil ettiğini tahmin edebiliyorum . a
Hatalara yardımcı olmanın faydasını görmüyorum LoaderException
. Haklı mıyım?
Bir ad alanında tüm türleri alamazsınız, çünkü bir ad alanı birden fazla montajı köprüleyebilir, ancak bir montajdaki tüm sınıfları alabilir ve bu ad alanına ait olup olmadıklarını kontrol edebilirsiniz.
Assembly.GetTypes()
yerel derlemede çalışır veya önce bir derleme yükleyebilir ve sonra arayabilirsiniz GetTypes()
.
AppDomain.CurrentDomain.GetAssemblies
yardımcı olabilir.
Tıpkı @aku yanıtı gibi, ancak uzantı yöntemlerini kullanarak:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
Tüm sınıfları Ad Alanı adının bir bölümüne göre tek bir satırda alın:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
Ad alanları aslında çalışma zamanının tasarımında oldukça pasiftir ve öncelikle organizasyonel araçlar olarak hizmet eder. .NET'te bir türün Tam Adı, Ad Alanı ve Sınıf / Enum / Etc'den oluşur. Kombine. Yalnızca belirli bir montajdan geçmek istiyorsanız, montaj tarafından döndürülen türler arasında dolaşmanız yeterlidir. Türün değerini denetleyen GetExportedTypes () . Ad alanı . Geçerli AppDomain'de yüklü olan tüm derlemeleri gözden geçirmeye çalışıyorsanız, AppDomain.CurrentDomain'i kullanmayı gerektirir. GetAssemblies ()
//a simple combined code snippet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace MustHaveAttributes
{
class Program
{
static void Main ( string[] args )
{
Console.WriteLine ( " START " );
// what is in the assembly
Assembly a = Assembly.Load ( "MustHaveAttributes" );
Type[] types = a.GetTypes ();
foreach (Type t in types)
{
Console.WriteLine ( "Type is {0}", t );
}
Console.WriteLine (
"{0} types found", types.Length );
#region Linq
//#region Action
//string @namespace = "MustHaveAttributes";
//var q = from t in Assembly.GetExecutingAssembly ().GetTypes ()
// where t.IsClass && t.Namespace == @namespace
// select t;
//q.ToList ().ForEach ( t => Console.WriteLine ( t.Name ) );
//#endregion Action
#endregion
Console.ReadLine ();
Console.WriteLine ( " HIT A KEY TO EXIT " );
Console.WriteLine ( " END " );
}
} //eof Program
class ClassOne
{
} //eof class
class ClassTwo
{
} //eof class
[System.AttributeUsage ( System.AttributeTargets.Class |
System.AttributeTargets.Struct, AllowMultiple = true )]
public class AttributeClass : System.Attribute
{
public string MustHaveDescription { get; set; }
public string MusHaveVersion { get; set; }
public AttributeClass ( string mustHaveDescription, string mustHaveVersion )
{
MustHaveDescription = mustHaveDescription;
MusHaveVersion = mustHaveVersion;
}
} //eof class
} //eof namespace
AttributeClass
Adı ne MustHaveAttributes
hakkında? Bir sınıfın nitelikleri olup olmadığını test etmeyle ilgili hiçbir şey görmüyorum. Bu yardımcı olmaktan daha kafa karıştırıcı.
Oldukça basit
Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}