使用接口.NET C#

时间:2016-09-07 16:35:49

标签: c# .net generics interface xml-deserialization

方案

我有一些XML来自我想要反序列化的服务。

根据从服务返回的内容,XML可能略有不同(使用元素名称);但XML总是遵循一个共同的结构。

以下是XML可能的样子:

<ATemplate>
    <Name>SomeTemplate</Name>
    <TemplateItems>
        <ATemplateItem>
            <Name>SomeTemplateItem</Name>
            <TemplateFields>
                <ATemplateField>
                    <Name>SomeTemplateField</Name>
                    <Colour>Blue</Colour>
                </ATemplateField>
                ... more template fields
            </TemplateFields>
        </ATemplateItem>
        ... more template items
    </TemplateItems>
</ATemplate>

以上面的XML为例,我创建了一个ATemplate类,它可以很好地从XML中反序列化,相应地使用ATemplateItemATemplateField类:

public class ATemplate
{
    public string Name { get; set; }
    public List<ATemplateItem> TemplateItems { get; set; }
}

public class ATemplateItem
{
    public string Name { get; set; }
    public List<ATemplateField> TemplateFields { get; set; }
}

public class ATemplateField
{
    public string Name { get; set; }
    public string Colour { get; set; }
}

我使用此代码反序列化:

ATemplate template;
using (TextReader reader = new StringReader(xmlString))
{
    template = (ATemplate)new XmlSerializer(typeof(ATemplate)).Deserialize(reader);
}

到目前为止一切都很好。

曲线球

如果XML包含BTemplateBTemplateItemBTemplateField s,则可能出现相同的情况;仍然遵循上述结构。

所以我为这种情况创建了其他类:

public class BTemplate { ... }
public class BTemplateItem { ... }
public class BTemplateField { ... }

并使相关的类分别从我创建的ITemplateITemplateItemITemplateField继承而来:

接口

public class ITemplate
{
    public string Name { get; set; }
    public List<ITemplateItem> TemplateItems { get; set; }
}

public class ITemplateItem
{
    public string Name { get; set; }
    public List<ITemplateField> TemplateFields { get; set; }
}

public class ITemplateField
{
    public string Name { get; set; }
    public string Colour { get; set; }
}

这样我就可以创建一个函数,它可以循环遍历ITemplateItem和它们的ITemplateField并执行一些很酷的东西:

public void Foo(ITemplate template)
{
    foreach (var item in template.TemplateItems)
    {
        // do cool stuff
        foreach (var field in item.TemplateFields)
        {
            // do more cool stuff
        }
    }
}

需要注意的一些事项:

  • 在包含XML的对象中,我知道什么&#34;输入&#34; XML包含 - 给定我用来识别的枚举
  • 然后我使用switch语句来运行不同的方法,具体取决于所说的&#34;类型&#34;

通用方法?

现在,我不想在每种方法案例中对XML进行不同的反序列化,而是希望使用Generic方法进行反序列化。

所以我创建了一个,就像这样:

public ITemplate DeserializeTemplate<T>(string xmlString) where T : ITemplate
{
    using (TextReader reader = new StringReader(xmlString))
    {
        return (T)new XmlSerializer(typeof(T)).Deserialize(reader);
    }
}

并在特定方法中调用它,如下所示:

var template = DeserializeTemplate<ATemplate>(xmlString);

然后,我可以使用它返回的ITemplate,并将其传递给Foo(ITemplate template)以执行一些魔法和魔法。

但是...

目前还没有编译错误 - 但是我收到RunTime错误,因为它无法反序列化接口。

我认为这是因为它试图将ITemplate TemplateItems反序列化为ITemplateItem

我可以这样做吗?

我的问题是:

如何解决这个问题?

  • 我可以使用此通用反序列化方法吗?
  • 我是否需要在不同的方法中区别对待每个人?
  • 我是否还需要使用期望的类型使接口通用?

我正在把头撞在桌子上,所以我真的希望你能让人感到可爱。

与往常一样,您的意见,答案和建议非常感谢:)

0 个答案:

没有答案