设计时的类型比较失败,直到我重新启动Visual Studio

时间:2015-11-21 11:49:48

标签: c# design-time

我编写了一个类库,需要从项目中获取信息,并在设计时引用它。我想获取项目中类的类型,该类继承自类库中的抽象类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或执行期间没有问题。

Screenshot 1: BaseType

Screenshot 2: typeof(Deklaration)

1 个答案:

答案 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:

C# Type Comparison: Type.Equals vs operator ==