我在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>
参数。
俗气的部分:此Wrappers将使用确定的类型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/