Covariance with C#

后端 未结 2 399
孤独总比滥情好
孤独总比滥情好 2021-01-22 01:25

I met some interesting covariance problem in my c# code.

I have a generic Matrix class, and it\'s been instantiated for example Matrix

相关标签:
2条回答
  • 2021-01-22 01:52

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

    How to use:

    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.

    Here is the Demo which outputs

    Serializing Wrapper`1[System.Object]
    Serializing Wrapper`1[System.String]
    Serializing Wrapper`1[System.Int32]
    
    0 讨论(0)
  • 2021-01-22 01:52

    You have said that you want to be able to insert data into the collection based on the covariantly exposed type. This is simply not possible. For a type to be covariant it needs to not expose any means of inserting data. The type would need to be contravariant to support that, but if the type is contravariant then it cannot expose the information in a covariant manor.

    In short, this is impossible, and not just impossible because of what C# as a language has implemented, but impossible on a conceptual level. It's not possible to implement a statically typed solution to this problem in any conceivable language.

    0 讨论(0)
提交回复
热议问题