c# - 我可以使用泛型方法作为一种模板模式吗?

标签 c# .net generics design-patterns

您好,我不确定通用方法是否是解决我的问题的正确方法。我需要解析一个 XML 文件并从中读取项目。项目可以是订单行、注释、附件之类的东西。获得这些元素的基本步骤都是一样的。我如何制作一种方法来创建这些项目的列表并调用特定方法来读取项目?

    public override IList<T> GetItems<T>(XPathNavigator currentOrder) where T : ISortableByLineNumber, new ()
    {
        var itemList = new List<T>();
        var itemXmlNodes = currentOrder.Select(OrderXPath);
        if (itemXmlNodes == null)
            throw new Exception("");
        var lineNumber = 1;
        foreach (XPathNavigator itemXmlNode in itemXmlNodes)
        {
            var item = new T();
            item = ReadItem(itemXmlNode, lineNumber++, item);
            itemList.Add(item);
            Logger.Debug(string.Format("Added item {0}", item));
        }
        return itemList;
    }

我想我可以用 ReadItem 方法来做到这一点。我会为我要阅读的每种类型的项目创建重载。

    private ISortableByLineNumber ReadItem(XPathNavigator itemXmlNode, int i, OrderLine item)
    {
        // specific code to read a orderLine
    }

    private ISortableByLineNumber ReadItem(XPathNavigator itemXmlNode, int i, Note item)
    {
        // specific code to read a note
    }

但是当我尝试编译它时,我会得到“'XmlOrderParser.XmlOrders.Prs3XmlFileWithOrders.ReadItem(System.Xml.XPath.XPathNavigator, int, XmlOrderParser.Entities.OrderLine)' 的最佳重载方法匹配有一些无效参数”。问题是编译器不知道如何将 T 转换为 OrderLine 或 Note。

最佳答案

如果您使用的是 .NET 4,则只需更改一件事即可使用新的 dynamic 类型:

dynamic item = new T(); // instead of var item = new T();

因为 item 现在是 dynamic 运行时会根据项目的实际类型自动进行重载解析。
请注意,如果 T 是不存在重载的类型,您将收到一个运行时异常。


以下片段演示了您的问题(粘贴到 LINQPad 并选择“C# 程序”作为语言):

void Main()
{
    Method<Class1>(); // Outputs Class1
    Method<Class2>(); // Outputs Class2
    Method<Class2b>(); // Outputs Class2, because it falls back to the base type
    Method<Class3>(); // Throws exception
}

void Method<T>() where T : new()
{
    dynamic c = new T();
    Method(c);
}

void Method(Class1 c) { Console.WriteLine("Class1"); }
void Method(Class2 c) { Console.WriteLine("Class2"); }

class Class1 {}
class Class2 {}
class Class2b : Class2 {}
class Class3 {}

关于c# - 我可以使用泛型方法作为一种模板模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8971414/

相关文章:

asp.net - 间歇性 ASP.Net 状态服务错误

java - 如何执行检查类型转换?

c# - 如何在 Visual Studio 单元测试中使用包含私有(private)类型的泛型

swift - 使用 Swift `is` 检查泛型类型

c# - 将 CRC16 计算从 C 转换为 C#

c# - 如果在附加 Visual Studio 调试器的情况下启动,为什么 "ShowDialog"的异常抛出行为会有所不同?

c# - 如何从路线获取数组?

c# - 报错不能在静态类中声明实例成员

c# - 那种异步的感觉——httpclient 和 mvc 线程阻塞

.net - 在 XML 属性上使用冒号字符时出错