有没有办法转换类型参数?

时间:2015-05-01 06:17:18

标签: c#

我可以使用type参数在没有Reflection的运行时实现特定的接口吗? 以下伪代码就是我想要做的。

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

void Run2<T> () where T : IEnumerable
{
    // ...
}

2 个答案:

答案 0 :(得分:4)

不,我不相信你能做到这一点很简单。

如果您控制了所有代码,那么您可以拥有带有约束的{em> public 版本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 }

#Call cmake with the given options
cmake -D CMAKE_TOOLCHAIN_FILE=$cross_cmp_file \
      -D BUILD_TESTS:BOOLEAN=$build_test \
      ../src 

答案 1 :(得分:1)

如果你要放弃不使用反射的要求,你可以稍微绕道而行。

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

请注意,通过按需构建和缓存特定类型的委托,可以提高效率。

输出:

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]