C#如何创建泛型类型参数

时间:2019-01-10 22:03:25

标签: c# .net generics types

我有现有的测试代码,需要扩展。

为了减少代码重复,我想尽可能保持通用性,这是当前代码的简化片段:


    public class FilterValueOne { }

    [TestClass]
    public class TestClass
    {
        [TestMethod]
        public void FilterValueOne_TestMethod()
        {
            ManipulateData(BuildFilter());
        }

        private void ManipulateData(FilterValueOne filter)
        {
            // Do some stuff with filter
        }

        private FilterValueOne BuildFilter()
        {
            var filter = new FilterValueOne();
            // Initialize filter data members here...
            return filter;
        }
    }

这有效,但仅限于“ FilterValueOne”类型。

我想扩展它,并通过实现泛型类型参数使其更通用。

下面的代码段是我想要的:


    // Enum will expand as the app grows
    public enum TypeEnum
    {
        ValueOne,
        ValueTwo,
        ValueThree
    }

    // More classes will be added as the app grows
    public class FilterValueOne { }
    public class FilterValueTwo { }
    public class FilterValueThree { }

    [TestClass]
    public class TestClassGeneric
    {
        // _filter to be used as the generic type argument
        private object _filter;

        // Constructor
        public TestClassGeneric(TypeEnum val)
        {
           switch (val)
           {
               case TypeEnum.ValueOne:
                   _filter = GetTestObject<FilterValueOne>();
                   break;
               case TypeEnum.ValueTwo:
                   _filter = GetTestObject<FilterValueTwo>();
                   break;
               case TypeEnum.ValueThree:
                   _filter = GetTestObject<FilterValueThree>();
                   break;
               default:
                   _filter = null;
                   break;
           }
        }

        private T GetTestObject<T>()
          where T : class
        {
           // Code simplified
           object returnValue = new object();
           return (T)returnValue;
        }

        [TestMethod]
        public void Generic_FilterValue_TestMethod()
        {
            // Error: The type _filter could not be found. (However it exists)
            ManipulateData(BuildFilter<_filter>());
        }

        private void ManipulateData<T>(T filter)
        {
            // Do some stuff with filter
        }    

        private T BuildFilter<T>()
         where T : class
        {
            // I want filter to be dynamically assigned to whatever _filter was
            // assigned to in the constructor (FilterValueOne/Two/Three), instead 
            // of "FilterValueOne"

            var filter = typeof(T);

            // Initialize filter data members here...

            return filter;
        }
    }

我最终想在测试方法中使用“ _filter”作为泛型类型参数,但是我无法使其正常工作。我收到一条错误消息,指出“找不到_filter”。

我尝试了多种使用typeof(_filter)等的方法,但没有成功。

我不完全了解泛型及其潜力,我不知道这是否有可能,或者我只是缺少某些东西。

2 个答案:

答案 0 :(得分:2)

T中的BuildFilter<T>是类型参数。您正在传递类型的实例,在这种情况下,您传递的是object(又名System.Object)实例而不是类型。

您根本无法做到这一点,因此会导致编译器错误(_filter不是 类型;它是一个实例,这就是为什么编译器找不到该“类型”的原因)。 / p>

您要做的是实例化特定的BuildFilter<FilterValueOne>等,并创建测试这些功能的测试。

例如

[TestMethod]
public void Generic_FilterValueOne_TestMethod()
{
    ManipulateData(new BuildFilter<FilterValueOne>());
}

您似乎正在使用MS Test; AFAIK MS Test不支持通用测试,因此您必须为感兴趣的每种类型创建一个测试。

答案 1 :(得分:0)

使用通用测试类更容易,但是如果您希望通过构造器传递过滤器类型,或者将其用作方法参数,则可以使用Activator类。

public class TestClassGeneric<T> where T : new()
{
    public void Generic_FilterValue_TestMethod()
    {
        var filter = new T();
        // ManipulateData(filter);
    }
}

public class TestClassConstructorArg
{
    private readonly Type type;

    public TestClassConstructorArg(Type type)
    {
        this.type = type;
    }

    public void Generic_FilterValue_TestMethod()
    {
        var filter = Activator.CreateInstance(type);
        // var filter = Activator.CreateInstance(type, BindingFlags.CreateInstance, arguments...);
        // ManipulateData(filter);
    }
}