我正在重申这个问题以总结我已经发现的内容:
我有一个测试 TypeConverter,(MyConverter),对于 ConvertToString,无论输入是什么,它都会输出“Converted To String”。
为了确保 GetConverter 为 Int32 拾取这一点,我添加了以下行:
(1) Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
下一个:
(2) Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Int32)) // Get the Int32 converter
(3) Console.WriteLine(tc.ConvertToString(12)) // The output is, as expected, "Converted To String"
下一个:
(4) TypeDescriptor.RemoveProvider(tcp, GetType(Int32)) //Remove the TypeConverterAttribute associated with int32
(5) tc = TypeDescriptor.GetConverter(GetType(Int32)) //Get Int32 TypeConverter
(6) Console.WriteLine(tc.ConvertToString(12)) //The output is STILL "Converted To String"
然而:
Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
TypeDescriptor.RemoveProvider(tcp, GetType(Int32)) //Immediately remove the provider
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Int32))
Console.WriteLine(tc.ConvertToString(12)) //The output is, as expected, "12"
似乎第 (2) 行正在创建一些其他的关联,它没有被 RemoveProvider 删除,因为 RemoveProvider 在该行之前工作,但不是在之后。
此外,在第 (4) 行和第 (5) 行之间,如果我执行 TypeDescriptor.GetAttributes(GetType(Int32)),则 TypeConverterAttribute 已按预期被删除。
呻吟……又是一个 ETA。
如果在第 (1) 行之前添加...
Dim OriginalProvider As TypeDescriptionProvider = TypeDescriptor.GetProvider(GetType(Int32))
然后在第(4)行之后我添加......
TypeDescriptor.AddProvider(OriginalProvider, GetType(Int32))
有用。但是在我删除了我的自定义提供程序之后,原始提供程序应该是堆栈中的下一个。
预计到达时间。我想我已经搞定了。
忽略关于重新添加 OriginalProvider 的最后一条评论。相反,在第 (4) 行之后,添加...
TypeDescriptor.Refresh(GetType(Int32))
出于某种原因,Remove 之后没有调用 Refresh。
如果您在类型的 Nullable 上使用了 GetConverter,则还需要刷新可为空的。所以如果我说:
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
删除提供程序后,我需要输入:
TypeDescriptor.Refresh(GetType(Int32))
TypeDescriptor.Refresh(GetType(Nullable(Of Int32)))
----原始问题----
为了强制可空类型使用自定义转换器,我添加了一个 TypeConverterAttribute 行:
TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
这样,以下行将使用 MyConverter 作为底层转换器选择一个可为空的转换器:
Converter = TypeDescriptor.GetConverter(GetType(Int32))
但是,一旦完成,我就看不到将 MyConverter 与 Int32 解除关联的方法,因为没有 TypeDescriptor.RemoveAttribute。
有任何想法吗?
预计到达时间:
好的,我已经成功了一半。
我发现 TypeDescriptor.AddAttributes 返回一个 TypeDescriptionProvider 然后我可以删除它。但是,它没有按预期工作。
这有效:
Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
TypeDescriptor.RemoveProvider(tcp, GetType(Int32))
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
Console.WriteLine(tc.ConvertToString(12)) '12 is output
正如预期的那样,原始转换器被拾取,而 MyConverter 被忽略。
但是,这不起作用:
Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
Console.WriteLine(tc.ConvertToString(12))
TypeDescriptor.RemoveProvider(tcp, GetType(Int32))
tc = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
Console.WriteLine(tc.ConvertToString(12))
在 RemoveProvider 之后,GetConverter 仍然拾取 MyConverter - 只是因为我在原始 GetConverter 之后移动了它!
再一次,有什么想法吗?
ETA2:
我已经通过在 GetConverter 方法上指定 noCustomTypeDesc 标志来解决问题,但我仍然想知道发生了什么。
删除提供程序后,我使用 TypeDescriptor.GetAttributes(GetType(Int32)) 列出所有属性,TypeConverterAttribute 确实消失了,但 GetConverter 继续获取 MyConverter。