Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml T的重载扩展方法_Xml_Vb.net_Reflection_Types_Extension Methods - Fatal编程技术网

Xml T的重载扩展方法

Xml T的重载扩展方法,xml,vb.net,reflection,types,extension-methods,Xml,Vb.net,Reflection,Types,Extension Methods,我想通过实例的属性创建一个XML文档。为此,我编写了两个扩展 公共函数ToXml(Of T)(ByVal源代码为T)作为XmlDocument Dim oXmlDocument作为新的XmlDocument AppendChild(oXmlDocument.CreateXmlDeclaration(“1.0”,“utf-8”,Nothing)) AppendChild(oXmlDocument.CreateElement(XmlConvert.EncodeName(source.GetType

我想通过实例的属性创建一个XML文档。为此,我编写了两个扩展


公共函数ToXml(Of T)(ByVal源代码为T)作为XmlDocument
Dim oXmlDocument作为新的XmlDocument
AppendChild(oXmlDocument.CreateXmlDeclaration(“1.0”,“utf-8”,Nothing))
AppendChild(oXmlDocument.CreateElement(XmlConvert.EncodeName(source.GetType.ToString)))
对于source.GetType.GetFields中的System.Reflection.FieldInfo等每个项
Dim oElement作为XmlElement=oXmlDocument.CreateElement(Item.Name)
oElement.Attributes.Append(oXmlDocument.CreateAttribute(“值”)).Value=Item.GetValue(Nothing.ToString
oXmlDocument.DocumentElement.AppendChild(oElement)
下一个
返回OXML文档
端函数
公共函数ToXml(Of T)(ByVal源代码为IEnumerable(Of T))作为XmlDocument
Dim oXmlDocument作为新的XmlDocument
AppendChild(oXmlDocument.CreateXmlDeclaration(“1.0”,“utf-8”,Nothing))
AppendChild(oXmlDocument.CreateElement(XmlConvert.EncodeName(source.GetType.ToString)))
对于源中的每一项作为T
oXmlDocument.DocumentElement.AppendChild(oXmlDocument.ImportNode(Item.ToXml.DocumentElement,True))
下一个
返回OXML文档
端函数
第二种方法适用于
IEnumerable(Of T)
的类型,第一种方法适用于所有其他类型。如果我在
按钮
字符串
Int32
或类似的实例中尝试它,效果会很好。对于实例,即
List(of T)
,也将调用第一个方法。似乎忽略了
IEnumerable(Of T)
的扩展,因为T的扩展范围更广

是否有可能强制
列表(Of T)
使用
IEnumerable(Of T)
的扩展名?

不包括泛型约束,因此用
As
子句调整
Of T
似乎没有帮助

对于简单(非泛型)接口,也会出现相同的“问题”,即选择与类最接近的匹配项,以便重载使用

请注意,对于某些类,
List(Of Integer)
例如,这两个签名是
ToXml(List(Of Integer))
ToXml(IEnumerable(Of Integer))
,因此它将明确选择前者,这是一个精确匹配

由于“不是最具体的”错误,我甚至没有一个解决方案可以让你给未来的程序员一个提示,他们调用了错误的例程。我所能建议的最好方法是不要对可以是列表的对象使用重载:-(

也就是说,拥有
ToXmlFromObject(Of T)(ByVal源为T)
ToXmlFromList(Of T)(ByVal源为IEnumerable(Of T))

并且,在运行时(:-(),您可以使用
ToXmlFromObject
中的反射来检查枚举的使用情况


我还应该提到一些错误消息暗示的另一个选项:您可以继续重载
ToXml(As T)
ToXml(As IEnumerable(Of T))
,但不要依赖于隐含的重载。例如,显式列出
(Of ElementType)
以确保
ToXml(Of ElementType)(As IEnumerable(Of ElementType))
version被调用。(当您确实有
SomeType
实现
IEnumerable(SomeType)
时,此操作仍然会失败)


错误答案 正如我在评论中提到的,这失败了,因为您希望在
IEnumerable(Of)
cast中指定一个不同的类型
T

另外,我现在注意到这将失败,因为使用
IEnumerable(任何内容)
调用
ToXml
会出错,因为上面描述的两个签名都是相同的,所以它会出现“重载解析失败,因为没有可访问的'ToXml'对这些参数最具体:……不是最具体的……不是最具体的”的错误

我认为您唯一的选择是在另一个方向手动“强制”重载;即,在确切的情况下,检查接口是否匹配,并调用该重载:


公共函数ToXml(Of T)(ByVal源代码为T)作为XmlDocument
Dim enumSource=TryCast(源,IEnumerable(共T个))
如果enumSource不是Nothing,则返回ToXml(enumSource)
...

我已经编辑了你的标题。请参见“”,其中的共识是“不,他们不应该”。
Debug.Assert(GetType(T) Is GetType(String) _
    OrElse Not (From i In GetType(T).GetInterfaces() _
        Where i Is GetType(IEnumerable)).Any)