繁体   English   中英

TypeConverter.ConvertTo中的“指定的转换无效”错误

[英]“Specified cast is not valid” error in TypeConverter.ConvertTo

我正在为Winform程序进行控制,并且在保存测试表单时会发生此错误。

错误


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

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

该控件附加有TypeConverter ,这是简短的代码。

为了简化问题,我省略了其他方法,您可以从此链接中阅读

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);
    }
}

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

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

经过一些调试后,我发现此行发生错误:

var state = (State)value;

起初我猜值是空的,所以我添加了一些日志:

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

因此,值不为null,值的类型恰好是我强制转换为的类型。


更新

输出AssemblyQualifiedName IsAssignableFrom为:

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



两个问题:

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

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

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

  1. 打开AssemblyInfo.CS并更改部件版本属性以更改每个内部版本中部件的内部版本号并保存文件。 这将迫使CLR使其缓存无效,并从新版本的程序集中加载新类型:

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

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

    <Deterministic>false</Deterministic>

这个论坛帖子已经解决了这个问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM