我编写了一个类库,需要从项目中获取信息,并在设计时引用它。我想获取项目中类的类型,该类继承自类库中的抽象类Deklaration
。在这种情况下,它将是Variablen
这在大多数情况下非常有效,函数GetAssembly()
返回正确的程序集,并且在大多数情况下GetMyDeclaration()
返回正确的类型。
图书馆代码:
/// <summary>
/// Get the assembly where the vars are declared in
/// </summary>
/// <returns></returns>
public static Assembly GetAssembly()
{
Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblys)
if (assembly.EntryPoint != null)
if (!assembly.FullName.Contains("vshost"))
return assembly;
return null;
}
/// <summary>
/// Get the container where all the vars are declarated in (inherited from clas "Deklaration"
/// </summary>
/// <returns></returns>
public static Type GetMyDeclaration()
{
Assembly myAssembly = GetAssembly();
if (myAssembly != null)
foreach (Type declaration in myAssembly.GetTypes())
if (declaration.BaseType == typeof(Deklaration))//1st point where I get stuck, can be fixed with .FullName comparison
return declaration;
return null;
}
/// <summary>
/// Get the declaring fieldinfo of the given object
/// </summary>
/// <param name="ojb"></param>
/// <returns></returns>
public static FieldInfo MyField(object ojb)
{
Type myDeclaration = GetMyDeclaration();
if (myDeclaration == null)
return null;
foreach (FieldInfo field in myDeclaration.GetFields())
if (field.GetValue(null) == ojb)//2nd point where I get stuck
return field;
return null;
}
/// <summary>
/// Get the full name of the declaration of an object like "HMI.Variablen.M0_0"
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string FullName(object obj)
{
var field = MyField(obj);
if (field == null)
return "Restart Visual Studio!";
return field.DeclaringType.FullName + "." + field.Name;
}
项目代码:
public class Variablen : Deklaration
{
public static BOOL M0_0 = new BOOL("DB100.DBX0.0");//Full Name: HMI.Variablen.M0_0
public static BOOL M0_1 = new BOOL("DB100.DBX0.1");//Full Name: HMI.Variablen.M0_1
public static BOOL M0_2 = new BOOL("DB100.DBX0.2");//...
public static BOOL M0_3 = new BOOL("DB100.DBX0.3");
public static BOOL M0_4 = new BOOL("DB100.DBX0.3");
public static BOOL M0_5 = new BOOL("DB100.DBX0.4");
public static BOOL M0_7 = new BOOL("DB100.DBX0.4");
}
一切正常,直到我修改项目中的类Variablen
并重建它(添加新声明或更改现有声明)
之后,行if (t.BaseType == typeof(Deklaration))
总是返回&#34; false&#34;。调试显示a.GetTypes()
返回Variablen' with BaseType
Deklaration`但类型比较失败。
我认为这必须对incosistency做一些事情,但重建或清理解决方案并没有帮助。
当我重新启动VisualStudio时,一切正常(只是关闭并打开灵魂不起作用)
我可以优化我的代码吗? 或者也许我可以打电话给&#34;刷新&#34;或&#34;清除&#34; Visual Studio?
更新
这是关于&#34;销毁&#34;引用。即使我使用
进行比较if (t.BaseType.FullName == typeof(Deklaration).FullName)
比较参考时,我会在几步之后遇到更多问题。
private FieldInfo MyField()
{
Type t = BASE.GetMyDeclaration();
if (t == null)
return null;
foreach (FieldInfo i in t.GetFields())
if (i.GetValue(null) == this) //never gets true after compile
return i;
return null;
}
所以在我看来,只有重置或重新加载Visual Studio才能工作。如果我能让代码在发生错误时自动执行此操作会很酷,但我不知道是否有函数...
这也只是设计时和编译后的问题。重新启动Visual Studio或执行期间没有问题。
答案 0 :(得分:0)
我无法重现您的问题,但类型比较似乎有点错误,您不应该将类型与==
运算符进行比较,因为您可能会比较引用相等或实际上错误的运行时类型。
你可以试试这个
if (typeof(Deklaration).IsAssignableFrom(t))
如果这不起作用,您可能还会考虑使用TypeDelegator
而不是正常的类型比较,因为它可以使用它的保护程序。
Type type = new TypeDelegator(typeof(int));
Console.WriteLine(type.Equals(typeof(int))); // Prints True
Console.WriteLine(type == typeof(int)); // Prints False
在你的情况下可能:
Type type = new TypeDelegator(t);
type.BaseType.Equals(typeof (Deklaration));
我建议您使用所有这些方法制作一些Console.WriteLine
调试输出,看看哪些方法仍然为您的案例返回正确的类型。
这里的一些信息来自SO SO: