在重新启动Visual Studio之前,设计时的类型比较将失败
本文关键字:类型 比较 失败 Visual 重新启动 Studio 之前 | 更新日期: 2023-09-27 18:23:42
我编写了一个类库,需要从设计时引用它的项目中获取信息。我想获得项目中从类库中的抽象类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))
总是返回"false"。调试显示a.GetTypes()
返回Variablen' with BaseType
Deklaration`但类型比较失败。
我认为这与不一致有关,但重建或清理解决方案无济于事。
当我重新启动VisualStudio时,一切都好(只是关闭和打开灵魂不起作用)
我可以优化我的代码吗?或者,我是否可以调用一个函数来"刷新"或"清除"Visual Studio?
更新
这主要是关于"已销毁"的引用。即使我使用进行比较
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之后或执行过程中都没有问题。
屏幕截图1:BaseType
屏幕截图2:(Deklaration)的类型
我无法重现您的问题,但类型比较似乎有点错误,您不应该使用==
运算符比较类型,因为您可能会比较引用相等或实际错误的运行时类型。
你可以试试这个
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 Post:
C#类型比较:Type.Equals vs运算符==