我想了解为什么下面的代码不能像预期的那样工作TypeDescriptor根本不是从属性中获取自定义转换器.我只能假设我犯了一个明显的错误,但我看不到它.
– 编辑 – 当我在自己的控制台中运行时,这段代码似乎工作,我实际上是从一个更复杂的应用程序和不同的命名空间中调用一个转换器.
– 编辑 – 或者任何关于如何调试TypeDescriptor的建议,以便我可以看到发生了什么,然后我可以自己回答这个.
– 编辑 – 这个问题几乎肯定与不同的程序集中的程序有关.
– 编辑 – 看起来这不起作用,因为动态加载程序集的一些奇怪 – 这个代码运行在像架构这样的插件.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.ComponentModel; namespace MyTest { public class TestTester { public static void Main(string[] args) { object v = TypeDescriptor.GetConverter(typeof(MyTest.Test)).ConvertFromInvariantString("Test"); } } public class TestConverter : TypeConverter { public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return false; } public override bool CanConvertFrom(ITypeDescriptorContext context,System.Type sourceType) { if (sourceType == typeof(string) || base.CanConvertFrom(context,sourceType)) { return true; } return base.CanConvertFrom(context,sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context,Type destinationType) { if (destinationType == typeof(Test) || base.CanConvertTo(destinationType)) { return true; } return base.CanConvertTo(context,destinationType); } public override object ConvertFrom(ITypeDescriptorContext context,System.Globalization.CultureInfo culture,object value) { if (value.GetType() == typeof(string)) { Test t = new Test(); t.TestMember = value as string; return t; } return base.ConvertFrom(context,culture,value); } public override object ConvertTo(ITypeDescriptorContext context,object value,Type destinationType) { if (destinationType == typeof(string) && value.GetType() == typeof(Test)) { return ((Test)value).TestMember; } return base.ConvertTo(context,value,destinationType); } } [TypeConverterAttribute(typeof(TestConverter))] public struct Test { public string TestMember { get; set; } } }
解决方法
我也有这个问题,解决问题的方法是订阅当前应用程序域的AssemblyResolve事件并手动解析程序集.
这远远不是一个很好的解决方案,但它似乎工作.我不知道为什么框架以这种方式行事.我真的很想找到一个更少的黑客方法来解决这个问题.
public void DoMagic() { // NOTE: After this,you can use your typeconverter. AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); } private Assembly CurrentDomain_AssemblyResolve(object sender,ResolveEventArgs args) { AppDomain domain = (AppDomain)sender; foreach (Assembly asm in domain.GetAssemblies()) { if (asm.FullName == args.Name) { return asm; } } return null; }