Wadim Smirnow
Wadim Smirnow

Reputation: 71

C# Loop through generic types known at compile time

Is there a way to call a generic function in a foreach loop for Types known at compile time? This code wont compile, because type is not a valid parameter for DoSmth, but illustrates what I want to do.

    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
        }
    }

Edit: Why is the question a duplicate? I specifically stated "known at compile time". The other uses Reflections to get the types not known at compile time.

Upvotes: 0

Views: 314

Answers (2)

Backs
Backs

Reputation: 24903

You can save delegates (Action) to your methods:

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
    }
}

Better way - use inheritance:

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();
        }
    }
}

Upvotes: 4

Chrille
Chrille

Reputation: 1453

Do you really have any use of generic in this case? Here's an example how you can solve it with 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...
    }
}

Upvotes: 1

Related Questions