与C#的协方差 [英] Covariance with C#

查看:103
本文介绍了与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 Wrappers. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆