1

我正在重申这个问题以总结我已经发现的内容:

我有一个测试 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。

4

0 回答 0