c# -从泛型接口指定结构字段类型

本文关键字:结构 字段 类型 泛型接口 | 更新日期: 2023-09-27 18:11:36

在c#中,是否可以创建这样的结构体?

我试图改变字段大小在PrimeStruct没有声明_myField作为一个接口,只是推迟关闭IData声明,直到PrimeStruct被创建。

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

(Like 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。

c# -从泛型接口指定结构字段类型

PrimeStruct还需要一个通用参数才能工作。

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

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

就像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