C# 是否有方法强制转换类型参数?

C# 是否有方法强制转换类型参数?,c#,C#,我可以在运行时使用类型参数作为实现特定接口而不进行反射吗? 下面的伪代码就是我想要做的 void Run1<T> () { // ... if (typeof (IEnumerable).IsAssignableFrom (typeof (T)) { Run2<T implementing IEnumerable> (); // <- use T as implementing IEnumerable } // ...

我可以在运行时使用类型参数作为实现特定接口而不进行反射吗? 下面的伪代码就是我想要做的

void Run1<T> ()
{
    // ...
    if (typeof (IEnumerable).IsAssignableFrom (typeof (T)) {
        Run2<T implementing IEnumerable> (); // <- use T as implementing IEnumerable
    }
    // ...
}

void Run2<T> () where T : IEnumerable
{
    // ...
}
void Run1()
{
// ...
if(typeof(IEnumerable).IsAssignableFrom(typeof(T)){

Run2();//不,我不相信有简单的方法可以做到这一点

如果您控制着所有的代码,您可以拥有带有约束的
Run2
的公共版本,但是没有约束的
Run2
的私有实现,您可以从
Run1
调用它:

public void Run1<T>()
{
    // ...
    if (typeof(IEnumerable).IsAssignableFrom(typeof(T))
    {
        Run2Impl<T>();
    }
    // ...
}

public void Run2<T>() where T : IEnumerable
{
    Run2Impl<T>();
}

private void Run2Impl<T>()
{
    // Need to cast any values of T to IEnumerable here
}
public void Run1()
{
// ...
if(typeof(IEnumerable).IsAssignableFrom(typeof(T))
{
Run2Impl();
}
// ...
}
public void Run2(),其中T:IEnumerable
{
Run2Impl();
}
私有void Run2Impl()
{
//这里需要将T的任何值强制转换为IEnumerable
}

如果要放弃不使用反射的要求,可以绕道一点

public class Tester
{
    private static readonly MethodInfo _run2Method = typeof(Tester).GetMethod("Run2");

    public void Run1<T>()
    {
        if (typeof(IEnumerable).IsAssignableFrom(typeof(T)))
            Run2AsIEnumerable<T>();
        else
            Console.WriteLine("Run1 for {0}", typeof(T));
    }

    public void Run2<T>() where T : IEnumerable
    {
        Console.WriteLine("Run2 for {0}", typeof(T));
    }

    private void Run2AsIEnumerable<T>()
    {
        Console.WriteLine("Detour to run2 for {0}", typeof(T));
        var method = _run2Method.MakeGenericMethod(typeof(T));
        method.Invoke(this, new object[0]);
    }
}

有了一点反射,看起来并没有那么难。@Alex:是的,反射可以做到——但是OP特别要求不使用反射的解决方案。
new Tester().Run1<IEnumerable<int>>();
Detour to run2 for System.Collections.Generic.IEnumerable`1[System.Int32]
Run2 for System.Collections.Generic.IEnumerable`1[System.Int32]