2

I want to do contravariancein override virtual method which implements from interface, I had try both ICloneTo<in T> and ICloneTo<out T> all getting compile errors, as the following code:

interface ICloneTo<T> {
    void CloneTo(T obj);
}

abstract class Base : ICloneTo<Base> {
    public string BaseProperty { get; set; }

    public virtual void CloneTo(Base obj) {
        obj.BaseProperty = BaseProperty;
    }
}

class A : Base {
    public string AProperty { get; set; }

    public override void CloneTo(A obj /* Contravariance to A */) {
        base.CloneTo(obj);
    
        obj.AProperty = AProperty;
    }
}
huang
  • 919
  • 11
  • 22
  • 1
    `all getting compile errors` I suggest that you post those errors and any other additional information that provides context that can help this be assessed efficiently. – Douglas Gaskell Feb 19 '22 at 03:18
  • The term "Clone" has a specific and well-understood definition in .NET which is different to yours (i.e. your `CloneTo` method does not behave anything like the well-known `ICloneable` interface), I suggest you rename your method to `CopyMembersInto` for greater clarity and to be self-documenting. – Dai Feb 19 '22 at 03:34
  • 1
    @Dai I'm sure this is a mockup of the problem, such pedantry isn't very helpful. OP did not come here for naming convention code review. – Douglas Gaskell Feb 19 '22 at 03:35
  • @Dai Yeah, these code even can not to compile, do you need I post the full project here? – huang Feb 19 '22 at 03:37
  • I'm curious why `ICloneTo` even needs to exist in the first place when the calls are going through `base.CloneTo` which doesn't involve any interfaces at all (they're self vtable calls, and [you can't meaningfully cast `base` to an interface type either](https://stackoverflow.com/questions/5976216/how-to-call-an-explicitly-implemented-interface-method-on-the-base-class)) - how are you intending to use it in consuming code? (e.g. what would your `Program.Main` method be doing?) – Dai Feb 19 '22 at 03:40

1 Answers1

1

There is no parameter contra-variance for method overriding in C# at this time.

This is the closest to a discussion on it I have found: https://github.com/dotnet/csharplang/discussions/3562

However, with some generic finagling, you can come up with:

    interface ICloneTo<T>
    {
        void CloneTo(T obj);
    }

    abstract class Base<T> : ICloneTo<T>
        where T : Base<T>
    {
        public string BaseProperty { get; set; }

        public virtual void CloneTo(T obj)
        {
            obj.BaseProperty = BaseProperty;
            throw new NotImplementedException();
        }
    }

    class A : Base<A>
    {
        public string AProperty { get; set; }

        public override void CloneTo(A obj /* Contravariance to A */)
        {
            base.CloneTo(obj);

            obj.AProperty = AProperty;
        }
    }

Though there are probably better ways to solve whatever problem you're trying to solve...

Douglas Gaskell
  • 9,017
  • 9
  • 71
  • 128