繁体   English   中英

IEnumerable 的泛型类型参数<Tx> ?

[英]IEnumerable of Generics Type Parameters <Tx>?

我正在寻找一种方法来改进以下结构的代码:

foreach (var operation in operations)
{
    if (IsTypeAndDoSomething<Type1>(operation))
    {
        Run((Type1)operation);
    }
    else if (IsTypeAndDoSomething<Type2>(operation))
    {
        Run((Type2)operation);
    }
etc.

我宁愿避免一长串else if块,它们始终具有基本相同的模式。

在这个项目中,我们创建了一个重载的 Run 方法来执行每个操作。 当操作列表正在运行时,我们需要先确定每个操作的类型,然后准备它(DoSomething 部分),然后再使用Run运行它。 目前,如果方法似乎有必要,请重复其他。

但是,我想知道在 C# 中是否有任何方法可以使上面的代码变得更加“通用”而无需重复else if s。

一个想法是创建一个类型的集合,例如

我想知道是否有任何方法可以将类型列表迭代为泛型类型参数?

var types = new[] {typeof(Type1), typeof(Type1)};

然后当我们添加一个新的操作实现时,我们可以简单地将它添加到该集合中(而不是多个else if块,我们有另一个迭代器)。

但是,我们需要以某种方式将每个项目作为 Tx 传递:

IsTypeAndDoSomething<Tx>

似乎不可能在泛型类型参数 (T) 中引用这些类型。 我认为这是因为它是在编译时而不是运行时完成的。

这是可能的还是有不同的模式推荐?

模式匹配的替代方法是使用访问者模式

你介绍一个访客界面

interface IOperationsVisitor<T> {
    T Visit(Type1 obj);
    T Visit(Type2 obj);
}

并为您的操作添加一个 Accept 方法到基类:

T Accept(IOperationsVisitor<T> visitor) => visitor.Visit(this);

然后,您只需实现访问者接口并调用对象上的Accept方法,并将访问者对象作为参数。

这比模式匹配要麻烦得多,但一个优点是,如果您引入新类型,您将被迫更新所有访问者以处理新类型。 使用模式匹配很容易忘记检查类型的所有地方。

只是写出问题帮助我看到答案是转换为非通用方法,即

 private bool IsTypeAndDoSomething(Type type, object operation)

通过此更改,类型在运行时处理,因此可以用以下内容替换重复匹配的 else if 块:

            var types = new[] {   
                                        typeof(Type1),
                                        typeof(Type2)
                                    };

            foreach (var operation in operations)
            {
                foreach (var type in types)
                {
                    if (IsTypeAndDoSomething(type, operation))
                    {
                        Run(operations, (dynamic) operation);
                    }
                }
            }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM