结构数组作为通用值

时间:2016-05-21 05:10:46

标签: c# generics

我正在尝试使用结构数组作为通用参数,如下所示:

new Test<S[,]>()

这很容易,除了我的班级需要创建T的实例,如下所示:

T s = new T();

这给了我各种编译时错误。我尝试了几种解决这些错误的方法,但没有成功。

以下是一些示例代码,用于说明错误以及我尝试过的内容:

class Program
{
    static void Main(string[] args)
    {
        var t1 = new Test<S[,]>();

        // ERROR: 'Program.S[*,*]' must be a non-abstract type
        // with a public parameterless constructor in order to
        // use it as parameter 'T' in the generic type or method
        // 'Program.Test2<T>'
        var t2 = new Test2<S[,]>();

        // ERROR: 'Program.S[*,*]' must be a non-nullable value
        // type in order to use it as parameter 'T' in the generic
        // type or method 'Program.Test3<T>'
        var t3 = new Test3<S[,]>();

        // ERROR: 'Program.S[*,*]' must be a non-nullable value
        // type in order to use it as parameter 'T' in the generic
        // type or method 'Program.Test3<T>'
        var t4 = new Test4<S[,]>();
    }

    struct S
    {
    }

    class Test<T>
    {
        // ERROR: Cannot create an instance of the variable type 'T'
        // because it does not have the new() constraint
        T s = new T();
    }

    class Test2<T> where T: new()
    {
        T s = new T();
    }

    class Test3<T> where T: struct
    {
        T s = new T();
    }

    // ERROR: The 'new()' constraint cannot be used with the 'struct' constraint
    class Test4<T> where T : struct, new()
    {
        T s = new T();
    }
}

这个问题有一个简单的方法吗?

1 个答案:

答案 0 :(得分:0)

您的错误会给您答案。 new()约束不能用于结构(new()和struct约束都不能一起使用)。 因此,除非必须将S作为结构,否则我会将S改为类并摆脱问题。但是你必须有S作为结构然后解决方法我建议创建一个包装类。

public class Wraper
{
    Wrapper(){}
    Wrapper(S value){
        this.Value = value;
    }

    public S Value {get; set;}

    public static implicit operator S(Wrapper wrapper){
        return wrapper. Value;
    }

    public static implicit operator Wraper(S s){
        return new Wrapper(S);
    }
}

现在您可以将Test定义如下:

class Test<T> where T : Wrapper, new()
{
    T value;

    //as you have provided implicit conversion from S to Wrapper and vice versa
    //something like this should work
    public S Value{
        get{ 
            //implicit conversion from Wrapper to S;
            return this.Value;
        }

        set{
            //implicit conversion from S to Wrapper
            this.value = value;
        }
    }
}