C#泛型:如何简化特定类型的调用

时间:2014-02-03 12:33:35

标签: c# generics types

我有这样的代码:

  if (args.ElementType == typeof(SomeFirstClassName))
  {
    args.Result = GetResult<SomeFirstClassName>(args);
  }
  else if (args.ElementType == typeof(SomeSecondClassName))
  {
    args.Result = GetResult<SomeSecondClassName>(args);
  }

如果我有多种类型,如何简化此代码? 例如,我可以做下面的事吗?

args.Result = this.GetResult<**args.ElementType**>(args);

我不能将变量Type( args.ElementType )放到&lt;&gt ;.它是C#的限制吗?

2 个答案:

答案 0 :(得分:1)

通过使用将类型映射到要调用的方法的字典,可以在不反映的情况下简化此操作。

以下是一个示例程序:

using System;
using System.Collections.Generic;

namespace Demo
{
    public class SomeFirstClassName{}

    public class SomeSecondClassName{}

    public class Result {}

    public class Args
    {
        public Result Result;
        public Type   ElementType;
    }

    internal class Program
    {
        private Dictionary<Type, Func<Args, Result>> map = new Dictionary<Type, Func<Args, Result>>();

        private void run()
        {
            init();

            var args1 = new Args {ElementType = typeof(SomeFirstClassName)};
            var args2 = new Args {ElementType = typeof(SomeSecondClassName)};

            test(args1); // Calls GetResult<T> for Demo.SomeFirstClassName.
            test(args2); // Calls GetResult<T> for Demo.SomeSecondClassName.
        }

        private void test(Args args)
        {
            args.Result = map[args.ElementType](args);
        }

        private void init()
        {
            map.Add(typeof(SomeFirstClassName),  GetResult<SomeFirstClassName>);
            map.Add(typeof(SomeSecondClassName), GetResult<SomeSecondClassName>);
        }

        public Result GetResult<T>(Args args)
        {
            Console.WriteLine("GetResult<T>() called for T = " + typeof(T).FullName);
            return null;
        }

        private static void Main()
        {
            new Program().run();
        }
    }
}

这使得调用网站更加简单(args.Result = map[args.ElementType](args);),但您仍需要为init()方法添加每种类型的初始化工具,如上所示。

然而,这至少将所有类型逻辑移动到单个方法(init())中,我认为这是一种更清晰,更易于维护的设计。


然而,我不禁想到,对于你想要实现的目标,将会有一个更好的面向对象的解决方案。但是我们需要更多关于你想做什么的信息(这看起来可能是X-Y目前的问题。)

答案 1 :(得分:0)

您的问题的答案是使用reflection。但是,如果您正在寻找一种不反思的解决方法,那么您可以将ElementType作为参数传入

GetResult<TElementType, TArgs>(TElementType elementType, TArgs args)

这会将您的代码减少为一次调用,即GetResult(args.ElementType, args)。它不是伟大的但它会给你你想要的东西。