在重新启动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)的类型

在重新启动Visual Studio之前,设计时的类型比较将失败

我无法重现您的问题,但类型比较似乎有点错误,您不应该使用==运算符比较类型,因为您可能会比较引用相等或实际错误的运行时类型。

你可以试试这个

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运算符==