与C#的协方差 [英] Covariance with C#
问题描述
我在C#代码中遇到了一些有趣的协方差问题。
I met some interesting covariance problem in my c# code.
我有一个通用的 Matrix< T>
类,并已实例化,例如 Matrix< int>
, Matrix< object>
和 Matrix< Apple>
。
I have a generic Matrix<T>
class, and it's been instantiated for example Matrix<int>
, Matrix<object>
and Matrix<Apple>
.
对于我的业务逻辑,我将它们包装在通用的 Wrapper< T
。该包装器实现了非通用的 INonGenericWrapper
接口。因此,我有 Wrapper< int>
, Wrapper< object>
和 Wrapper< Apple>
。
For my business logic, I've wrapped them into a generic Wrapper<T>
. This Wrapper implements non-generic INonGenericWrapper
interface. So, I have Wrapper<int>
, Wrapper<object>
and Wrapper<Apple>
.
我的问题是:我想为所有这3个包装器
s。我不能说 List< Wrapper< object>>
,因为我不能插入 Wrapper< int>
进入这个集合。我什至不能说 List< INonGenericWrapper>
,因为在我的foreach中,我想访问通用的 Matrix< T> $
My problem is: I would like to define a container for all those 3 Wrapper
s. I can't say List<Wrapper<object>>
, because I can't insert Wrapper<int>
into this collection. I can't even say List<INonGenericWrapper>
, because inside my foreach, I would like to access to the generic Matrix<T>
parameter.
俗气的部分:此Wrappers将使用以下确定的类型进行(反)序列化: MySerializer< Wrapper< Apple> > .Serialize(_myInstanceOfWrappedApple)
。
Cheesy part: this Wrappers will be (de-)serialized with the definite type: MySerializer<Wrapper<Apple>>.Serialize(_myInstanceOfWrappedApple)
.
我认为很明显,我想避免使用 typeof的巨大开关
进行序列化时。.
I think it's clear that I would like to avoid huge switches of typeof
when serializing..
可能的解决方法是什么?我有点被卡住了。
预先感谢
推荐答案
最近,我遇到了这样的限制,并实现了访问者模式的一种变体(可能是对它的滥用)。但这帮助我解决了这个问题。
Recently I've come across such limitation and I implemented a variation of Visitor Pattern (may be abuse of it). But that helped me to solve the problem.
我不是建筑师,只是开发人员。因此,请原谅我是否滥用设计模式,但是可以肯定会有所帮助。
I'm no architect, just a developer. So pardon me if am abusing the design pattern, but sure this will help.
利用提供的信息,我创建了类的模拟并按如下方式应用了访问者模式。
With provided information I created mocks of your classes and applied visitor pattern as follows.
public class Matrix<T>
{
public T Obj { get; set; }
}
public interface INonGenericWrapper
{
void Wrap();
void Accept(IVisitor visitor);
}
public class Wrapper<T> : INonGenericWrapper
{
public Matrix<T> Matrix { get; private set; }
public void Wrap()
{
//Your domain specific method
}
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
public interface IVisitor
{
void Visit<T>(T element);
}
public class SerializationVisitor : IVisitor
{
public void Visit<T>(T element)
{
new Serializer<T>().Serialize(element);
}
}
public class Serializer<T>
{
public Stream Serialize(T objectToSerialize)
{
Console.WriteLine("Serializing {0}", objectToSerialize);
//Your serialization logic here
return null;
}
}
使用方法:
List<INonGenericWrapper> wrappers = new List<INonGenericWrapper>();
wrappers.Add(new Wrapper<object>());
wrappers.Add(new Wrapper<string>());
wrappers.Add(new Wrapper<int>());
var visitor = new SerializationVisitor();//Create the operation you need to apply
foreach (var wrapper in wrappers)
{
wrapper.Accept(visitor);
}
您要做的就是为您需要的每个操作创建一个新的访问者
All you've to do is create a new visitor for each operation you need to perform.
这是演示,其输出
Serializing Wrapper`1[System.Object]
Serializing Wrapper`1[System.String]
Serializing Wrapper`1[System.Int32]
这篇关于与C#的协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!