C#循环遍历编译时已知的泛型类型

时间:2017-11-29 06:49:57

标签: c# generics

有没有办法在foreach循环中为编译时已知的类型调用泛型函数?这段代码不会编译,因为type不是DoSmth的有效参数,而是说明了我想要做的事情。

    public class X { }

    public class Y { }

    public class Z { }

    public class Example
    {
        public Example()
        {
            Types = new List<Type>
            {
                typeof(X),
                typeof(Y),
                typeof(Z)
            };
        }

        private List<Type> Types { get; }

        public void DoAllTypes()
        {
            foreach (var type in Types)
            {
                DoSmth<type>();
            }
        }

        private void DoSmth<T>()
        {
            // ... do smth based on T
        }
    }

编辑:为什么问题重复?我特别声明&#34;在编译时知道&#34;。另一个使用Reflection来获取编译时未知的类型。

2 个答案:

答案 0 :(得分:3)

您可以将代理人(Action)保存到您的方法中:

public class Example
{
    public Example()
    {
        Types = new List<Action>
        {
            DoSmth<X>,
            DoSmth<Y>,
            DoSmth<Z>
        };
    }

    private List<Action> Types { get; }

    public void DoAllTypes()
    {
        foreach (var type in Types)
        {
            type();
        }
    }

    private void DoSmth<T>()
    {
        // ... do smth based on T
    }
}

更好的方法 - 使用继承:

public class A
{
    public virtual void DoSmth()
    {
    }
}

public class X : A
{
    public override void DoSmth()
    {

    }
}

public class Y : A
{
    public override void DoSmth()
    {

    }
}

public class Z : A
{
    public override void DoSmth()
    {

    }
}

public class Example
{
    public Example()
    {
        Types = new List<A>
        {
            new X(),
            new Y(),
            new Z()
        };
    }

    private List<A> Types { get; }

    public void DoAllTypes()
    {
        foreach (var type in Types)
        {
            type.DoSmth();
        }
    }
}

答案 1 :(得分:1)

在这种情况下你真的使用泛型吗?以下是switch statements with pattern如何解决问题的示例。

public void DoAllTypes()
{
    foreach (var type in Types)
    {
        DoSmth(type);
    }
}

private void DoSmth(Type t)
{
    switch (this.value) {
        case X xval:
            //Handle type X
            break;
        case Y xval:
            //Handle type Y
            break;
        //And so on...
    }
}