我创建了Animal项目并将其设置为Library。当然在Animal项目中我会添加更多类。在这个项目中,我现在有两个班:狗和方法。
//Class Method
public class Method : Attribute{
public string Name { get; set; }
public Method(){
Name = "";
}
}
//Class Dog
[Method(Name = "dog")]
public class Dog
{
public int NumberOfLegs { get; set; }
public string Breed { get; set; }
public Dog() { }
}
然后我在我的解决方案Ref中创建了第二个项目,这是我的主要课程:
//version 1
class Program{
public static Dictionary<String, Type> animals;
static void Main(string[] args){
Assembly assembly = Assembly.GetEntryAssembly();
Type[] typ = assembly.GetTypes();
foreach (Type t in typ){
animals.Add(t.Name, t);
}
}
}
我想要成就“狗,狗”,“猫,猫”,“老鼠,老鼠”。其中“dog”是name属性,而“Dog”是一个类型,这要归功于我能够制作类似
的东西Activator.CreateInstance(animals[nameAnimal]);
但是现在我做错了什么,我的方式不起作用,我无法找到解决我在.net核心问题的解决方案。我只想要来自属性方法的类的对象。怎么实现呢?
修改 我的程序看不到库“Dog”并搜索“Ref。*”库,例如Ref,Ref.Program等。
答案 0 :(得分:0)
您的代码中存在一些问题:
NullReferenceException
; animals
是
null
。为什么要实现根本不使用的属性?
您正在程序集assembly.GetTypes();
中存储所有类型,并且您只想存储定义属性Method
的类型。
此外,t.Name
不是您的属性的属性,它是类型的名称; Type.Name
你可能想要的是:
var allTypes = assembly.GetTypes();
foreach (var t in allTypes)
{
var methodAttribute = t.GetCustomAttribute<Method>();
if (methodAttribute != null } animals.Add(methodAttribute.Name, t);
}
Method
应该有一个带有一个参数的构造函数,你的代码是不必要的复杂:
public Method(string name)
{
Name = name;
}
并且Name
应该只读:
public string Name { get; }
使用命名约定。属性应具有属性后缀:
public class MethodAttribute { ... }
编译器会做一些魔术并允许你以任何方式使用“短”名称:
[Method("Dog")]
public class Dog { ... }
答案 1 :(得分:0)
您可以使用以下代码安静..
Assembly assembly = Assembly.GetEntryAssembly();
Type[] typ = assembly.GetTypes();
foreach (Type t in typ)
{
IList<CustomAttributeData> m = t.GetCustomAttributesData();
if(m.Count>0)
animals.Add(t.Name, m[0].NamedArguments[0].TypedValue.Value.ToString());
}
答案 2 :(得分:0)
对不起我早先的愚蠢。我已经有更多的时间再次阅读所有内容。我现在认为我理解你的问题。您想知道的是为什么使用relection您没有看到其他两个类?原因很简单:这两个类不在同一个程序集中!你的第一个项目编译成一个DLL。这是它自己的集会。你的第二个项目编译成一个exe,这是另一个程序集。因此,在第二个装配体中使用反射,只显示第二个装配体中的类型。
要获得您想要的东西,只需将您的狗类从库中移出并将它们包含在您的第二个项目中。然后你就可以在Main看到它们。
修改
使用此:
Assembly assembly = Assembly.ReflectionOnlyLoadFrom("yourlibname.dll");
Type[] typ = assembly.GetTypes();
foreach (Type t in typ)
{
animals.Add(t.Name, t);
}
假设您一起编译解决方案,那么dll应该与您的exe在同一个bin文件夹中。否则你需要提供完整的路径。
答案 3 :(得分:0)
以下是完整的程序。
class Program
{
public static Dictionary<String, string> animals = new Dictionary<string, string>();
static void Main(string[] args)
{
Assembly assembly = Assembly.GetEntryAssembly();
Type[] typ = assembly.GetTypes();
foreach (Type t in typ)
{
IList<CustomAttributeData> m = t.GetCustomAttributesData();
if(m.Count>0)
animals.Add(t.Name, m[0].NamedArguments[0].TypedValue.Value.ToString());
}
}
}
public class Method : Attribute
{
public string Name { get; set; }
public Method()
{
Name = "";
}
}
//Class Dog
[Method(Name = "dog")]
public class Dog
{
public int NumberOfLegs { get; set; }
public string Breed { get; set; }
public Dog() { }
}
答案 4 :(得分:0)
您可以使用CustomAttributes
的{{1}}属性:
TypeInfo