C# - 从通用接口指定结构字段类型

时间:2014-07-06 22:59:04

标签: c# generics struct

在C#中,是否可以创建一个类似这样的结构?

我正在尝试改变PrimeStruct内的字段大小而不将_myField声明为接口,只是推迟关闭IData声明直到创建PrimeStruct。

我知道为什么这不起作用,但是试图找出是否有人将语法糖用于将PrimeStruct内容的类型声明推迟到包含的泛型类型。

(如PrimeStruct<T>

(毫不奇怪:这不会编译)

interface IBehavior { void Foo(); }

interface IData<T> where T : IBehavior { }

struct MyStruct1 : IBehavior
{
    public void Foo() { }
}

struct MyStruct2 : IBehavior
{
    public void Foo() { }
}

       //specifying an open type <T> here doesn't compile
public struct PrimeStruct : IData<T>, IBehavior
{
    T _myField;

    internal void SetData<T>(T value) where T : IBehavior
    {
        _myField = value;
    }

    public void Foo()
    {
        _myField.Foo();
    }
}

public class Runner
{
    public static void Main(string[] args)
    {
        PrimeStruct p = new PrimeStruct();
        p.SetData(new MyStruct1());
        p.Foo();
    }
}

或者这是否属于编译时未知的类型?我试图避免将_myField结构值装入接口或使用HAllocGlobal。

3 个答案:

答案 0 :(得分:1)

PrimeStruct还需要一个通用参数才能生效。

public struct PrimeStruct<T> : IData<T>, IBehavior

答案 1 :(得分:1)

由于IData<T>没有成员,因此不清楚您想要通用参数的内容。如果IData<T>的目的是将T约束为IBehavior,并提供获取和设置它的方法,我建议您IData<T>继承非IData通用IBehavior,其成员类型为IData;该方法可以提供属性getter和设置属性的方法,但该方法的文档应该清楚表明大多数非泛型IBehavior的实现只接受{{1}}的某些实现。 / p>

答案 2 :(得分:1)

就像supercat所说,从这段代码中我不清楚IData<T>是什么。如果您取消PrimeStruct实施IData<T>的要求,并将_myField更改为IBehavior,则会进行编译。

interface IBehavior { void Foo(); }

interface IData<T> where T : IBehavior { }

struct MyStruct1 : IBehavior
{
    public void Foo() { }
}

struct MyStruct2 : IBehavior
{
    public void Foo() { }
}

//specifying an open type <T> here doesn't compile
public struct PrimeStruct : IBehavior
{
    IBehavior _myField;

    internal void SetData<T>(T value) where T : IBehavior
    {
        _myField = value;
    }

    public void Foo()
    {
        _myField.Foo();
    }
}

public class Runner
{
    public static void Main(string[] args)
    {
        PrimeStruct p = new PrimeStruct();
        p.SetData(new MyStruct1());
        p.Foo();
    }
}

正如Preston Guillot所说,你不能拥有一个继承自开放泛型的非泛型类(即IData<T>)。

 PrimeStruct : IData<int> // Non-generic inherits from closed generic is OK
 PrimeStruct<T> : IData<T> // Open generic inherits from open generic is OK
 PrimeStruct : IData<T> // Non-generic inherits from open generic will not compile