“指定的演员表无效"TypeConverter.ConvertTo 中的错误 [英] "Specified cast is not valid" error in TypeConverter.ConvertTo

查看:36
本文介绍了“指定的演员表无效"TypeConverter.ConvertTo 中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的 winform 程序制作控件,并且在保存测试表单时发生此错误.

I'm making controls for my winform program, and this error happens when saving the test form.

这是解决方案结构,控件库分离在 1 个项目中,另一个是包含测试表单的测试项目.

This is the solution structure, the controls library is seperated in 1 project and another is a test project contains a test form.

Solution
├ Test (Test Project)
│ └ Form1
└ WinFormControls (Library Project)
  └ ImageButton (UserControl)

<小时>

该控件附有一个TypeConverter,这里是简短的代码.

为了简单起见,我省略了其他方法,你可以从此链接

To make the question simple, I omit other methods, you can read it from this link

public class StateConverter : ExpandableObjectConverter
{
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if(destinationType == typeof(InstanceDescriptor))
        {
            var ctor = typeof(State).GetConstructor(new Type[] { typeof(int), typeof(Image) });
            if (ctor != null)
            {
                var state = (State)value;
                return new InstanceDescriptor(ctor, new object[] { state.GetData(), state.Image });
            }
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

<小时>

错误并不总是发生在这里是重现的步骤:


The error is not always happens here are steps to reproduce:

  1. 在 VS 中打开解决方案
  2. 打开 Form1 设计器,从工具箱中拖出一个 ImageButton
  3. 在 ImageButton.cs 中进行一些更改(例如添加一个空格),然后重新构建解决方案
  4. 返回 Form1 设计器,在属性窗口中对 NormalState 属性进行一些更改,然后保存,出现错误.
  5. 此后,如果您对 ImageButton 进行更改并保存,则即使从工具箱中拖动另一个 ImageButton 也会显示错误,除非重新打开 VS.

<小时>

经过一些调试,我发现错误发生在这一行:


After some debug, I found the error occurs with this line:

var state = (State)value;

一开始我猜这个值是空的,所以我用它添加了一些日志:

At first I guessed the value is null, so I added some log with it:

try {
    var state = (State)value;
} catch (Exception ex) {
    File.AppendAllText("errorlog.txt", ex.ToString() +
       (value == null ? "NULL" : value.GetType().ToString());
}

我终于明白了:

System.InvalidCastException:指定的强制转换无效.在       WinFormControls.ImageButton.StateConverter.ConvertTo ......WinFormControls.ImageButton+State

System.InvalidCastException: Specified cast is not valid. at         WinFormControls.ImageButton.StateConverter.ConvertTo ...... WinFormControls.ImageButton+State

所以值不为空,值的类型正是我所投射的.

So the value is not null, and the type of value is exactly what I cast to.

更新

输出AssemblyQualifiedName,IsAssignableFrom,是:

Output AssemblyQualifiedName, IsAssignableFrom, is:

value.GetType().AssemblyQualifiedName;
typeof(State).AssemblyQualifiedName;
typeof(State).IsAssignableFrom(value.GetType());
value.GetType().IsAssignableFrom(typeof(State))
value is State
ReferenceEquals(value.GetType(), typeof(State))

奇怪的结果:

WinFormControls.ImageButton+State, WinFormControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
WinFormControls.ImageButton+State, WinFormControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
假的
假的
假的
错误

WinFormControls.ImageButton+State, WinFormControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
WinFormControls.ImageButton+State, WinFormControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
False
False
False
False

两个问题:

  1. 为什么会发生错误?
  2. 如何在开发过程中避免它?

推荐答案

这是因为类型转换器和设计器加载类型的方式不同.类型转换器使用 CLR 缓存来加载类型,而设计器使用类型解析服务.因此,当您更改类库项目并再次构建它时,CLR 从 CLR 中先前缓存的类型版本加载程序集,而设计器从新构建的程序集加载它并导致类型不匹配.

This is because of the different way that type converter and designer loads the type. Type converter uses CLR cache to load the type while designer uses type resolutions service. So when you change the class library project and build it again, the CLR loads the assembly from previously cached version of the type in CLR, while designer loads it from newly built assembly and it results in a type mismatch.

解决问题,在类库项目中:

To solve the problem, in the class library project:

  1. 打开 AssemblyInfo.CS 并更改程序集版本属性以更改每个构建中程序集的构建号并保存文件.这会强制 CLR 使其缓存无效并从新版本的程序集加载新类型:

  1. Open AssemblyInfo.CS and change assembly version attribute to change the build number of the assembly in each build and save the file. This forces the CLR to invalidate its cache and load the new type from the new version of assembly:

[assembly: AssemblyVersion("1.0.0.*")]

  1. 右击并卸载类库项目,然后右击并编辑项目文件并将项目确定性构建更改为false:

  1. Right click and unload the class library project, then right click and edit the project file and change the project deterministic build to false:

false

问题已经解决在此论坛帖子中.

这篇关于“指定的演员表无效"TypeConverter.ConvertTo 中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆