c# - 与 C# 的协方差

标签 c# covariance

我在我的 C# 代码中遇到了一些有趣的协方差问题。

我有一个通用的 Matrix<T>类,它已被实例化,例如 Matrix<int> , Matrix<object>Matrix<Apple> .

对于我的业务逻辑,我将它们包装到一个通用的 Wrapper<T> 中.此包装器实现非通用 INonGenericWrapper界面。所以,我有 Wrapper<int> , Wrapper<object>Wrapper<Apple> .

我的问题是:我想为所有这些 3 Wrapper 定义一个容器秒。我不能说List<Wrapper<object>> ,因为我无法插入 Wrapper<int>进入这个集合。我什至不能说 List<INonGenericWrapper> ,因为在我的 foreach 中,我想访问通用的 Matrix<T>参数。

俗气的部分:这个包装器将被(反)序列化为确定的类型:MySerializer<Wrapper<Apple>>.Serialize(_myInstanceOfWrappedApple) .

我想很明显我想避免大量切换 typeof序列化时..

我可能的解决方法是什么?我有点卡住了。

提前致谢

最佳答案

最近我遇到了这样的限制,我实现了 Visitor Pattern 的变体。 (可能是滥用它)。但这帮助我解决了问题。

我不是架构师,只是一名开发人员。如果我在滥用设计模式,请原谅我,但这肯定会有所帮助。

根据提供的信息,我创建了您的类的模拟并应用了访问者模式,如下所示。

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);
}

您所要做的就是为您需要执行的每个操作创建一个新访问者。

这是 Demo输出

Serializing Wrapper`1[System.Object]
Serializing Wrapper`1[System.String]
Serializing Wrapper`1[System.Int32]

关于c# - 与 C# 的协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23248537/

相关文章:

c# - TreeView AfterExpand 事件有时不起作用 C#

c# - 如何在 C# 中将维度 (100, 1) 的数组转换为 2 个单独的数组?

C#.NET : How do I create a new instance of a class based solely on a "Type" object?

java - 编译器如何区分 <? extends Number> from <Number> 当它们在类型删除后看起来都被编译成相同的东西时?

Scala:为什么不强制执行存在类型声明的下限?

c# - 委托(delegate)协方差混淆难题!

c# - 为什么我不能对两个泛型类型参数使用协变?

c# - 微星参数检查

c# - 在共享组件中将 .NET 中的访问修饰符从私有(private)更改为公共(public)是否是一项重大更改?

java - 在类中使用子类型作为类型参数