简体   繁体   English

将结构作为通用协变参数

[英]Put a struct as a generic covariant parameter

I've an Covariant interface, which is in an array of it's parent type.我有一个 Covariant 接口,它位于它的父类型的数组中。 They are defined globally like this:它们在全局定义如下:

//The interface/class
public interface IMyType<out T>{}
public class MyType<T>: IMyType<T>{
    T value;
    MyType<T>(T initialValue){
        value = initialValue;
    }
}

I tried this:我试过这个:

IMyType< object>[] tt = new IMyType<object>[]
{
    new MyType<String>( "test"), //Works fine
    new MyType<SomeOtherRandomClass>(new SomeOtherRandomClass()),//works fine
    new MyType<Int32>(12)//Doesn't work
};

Even trying to specify a struct instead of object:甚至试图指定一个结构而不是对象:

IMyType< struct>[] tt = new IMyType<struct>[]//Doesn't work:Incorrect Number of parameter
{
    new MyType<Int32>(12)//Doesn't work
};

Specifying only a specific struct works:仅指定特定结构有效:

IMyType< int>[] tt = new IMyType<int>[]//Does work
{
    new MyType<Int32>(12)//Does work
};

So why does this not work?那么为什么这不起作用呢? Is there a way to make it work?有没有办法让它工作?

It is completely impossible to convert an Interface<ValueType> to Interface<object> as a covariant conversion.Interface<ValueType>转换为Interface<object>作为协变转换是完全不可能的。

The reason for this is that the JITter must compile a separate version of your class for each value type (since value types have different shapes), so it cannot convert it to any other generic instantiation.这样做的原因是 JITter 必须为每个值类型编译一个单独的类版本(因为值类型具有不同的形状),因此它不能将它转换为任何其他通用实例化。

Variance only works for reference types because references are all the same, so the JITted methods can be shared across different type parameters.方差仅适用于引用类型,因为引用都是相同的,因此 JITted 方法可以在不同的类型参数之间共享。

Your best solution may be to write a wrapper class that encapsulates a struct:您最好的解决方案可能是编写一个封装结构的包装类:

public class StructContainer<TStruct> where TStruct : struct
{
    TStruct value;
    public StructContainer(TStruct initialValue)
    {
        value = initialValue;
    }
}

Then you could do:那么你可以这样做:

IMyType<object>[] tt = new IMyType<object>[]
{
    new MyType<String>("test"), //Works fine
    new MyType<StructContainer<int>>(
        new StructContainer<int>(12)
    ) // compiles now
};

Granted, this sacrifices the simplicity of your original syntax and forces you to do hokey things (like type checks) later on when you need to pull items out of your collection.诚然,这牺牲了原始语法的简单性,并迫使您稍后在需要从集合中提取项目时做一些复杂的事情(如类型检查)。

One other option is to track a collection of objects AND a collection of structs as separate collections.另一种选择是将对象集合和结构集合作为单独的集合进行跟踪。 This may make more sense because, again, once you pull items out of your list, it's likely that you'll need to treat them differently anyway.这可能更有意义,因为同样,一旦您将项目从列表中拉出,您可能需要以不同的方式对待它们。

If you want to accomplish putting generic types with different type parameters into the same collection, and you can't use covariance for the reason SLaks mentioned, then you should have the generic type implement a non-generic interface:如果你想完成将具有不同类型参数的泛型类型放入同一个集合中,并且由于 SLaks 提到的原因你不能使用协方差,那么你应该让泛型类型实现一个非泛型接口:

public interface IMyType<out T> : ISomeBaseInterface {}

var tt = new ISomeBaseInterface[] 
{
    new MyType<String>( "test"), //Works fine
    new MyType<SomeOtherRandomClass>(new SomeOtherRandomClass()),//works fine
    new MyType<Int32>(12)//now it works
};

This may or may not be sufficient depending on what your other requirements are.根据您的其他要求,这可能足够也可能不够。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c# 协变通用参数 - c# covariant generic parameter 协变接口不可能包含类型参数是协变类型的泛型类型吗? - Is it not possible to have a covariant interface contain a generic type who's type parameter is the covariant type? 是否有内置的通用接口,索引器返回了协变类型参数? - Is there a built-in generic interface with covariant type parameter returned by an indexer? StackOverflowException使用具有协变泛型参数的explict接口实现 - StackOverflowException by using explict interface implementation having covariant generic parameter 将通用结构转换为具有不同类型参数的相同通用结构 - Converting a generic struct to the same generic struct with different type parameter 当用作泛型类型参数时,为什么“动态”不是所有类型的协变和逆变? - Why is “dynamic” not covariant and contravariant with respect to all types when used as a generic type parameter? C#通用协变错误 - C# Generic Covariant Error 如果type参数是struct或class,则选择泛型实现 - Chose generic implementation if the type parameter is struct or class 当结构是在 C# 中转换的通用对象的协变类型时,结构无法转换为对象的任何解决方法? - Any workarounds for structs failing to cast to object when the struct is the covariant type of a generic object being being casted in C#? 如何将泛型(T)作为参数? - How to put generic Type (T) as parameter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM