使用继承时接口实现的问题

Problem with Interface Implementation When using Inheritance

我已经创建了 IShallowCloneable 接口来为我所有的 class 创建 class 的浅表副本,但是继承它不能正常工作。

查看 Main 方法,node2 返回的是 Point3D 对象而不是 Node。

详情

using System;

namespace ConsoleAppTest
{
    internal static class Program
    {
        private static void Main()
        {
            try
            {
                var node = new Node(1, 0, 0, 0);
                var node2 = node.ShallowClone();//this code is returing Point3D Object instead of Node
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }

    public interface IShallowCloneable<T>
    {
        T ShallowClone();
    }

    public class Point2D : IShallowCloneable<Point2D>
    {
        public int X { get; set; }
        public int Y { get; set; }

        public Point2D()
        {
        }
        public Point2D(int x, int y)
        {
            X = x;
            Y = y;
        }

        public Point2D ShallowClone()
        {
            return new Point2D(X, Y);
        }
    }
    public class Point3D : Point2D, IShallowCloneable<Point3D>
    {
        public int Z { get; set; }

        public Point3D()
        {
        }
        public Point3D(int x, int y,int z):base(x,y)
        {
            Z = z;
        }
        new public Point3D ShallowClone()
        {
            return new Point3D(X, Y,Z);
        }
    }

    public class Node:Point3D, IShallowCloneable<Node>
    {
        public int Id { get; set; }
        public Node()
        {

        }
        public Node(int id,int x, int y, int z):base(x,y,z)
        {
            Id = id;
        }

        Node IShallowCloneable<Node>.ShallowClone()
        {
            return new Node(Id,X, Y, Z);
        }
    }
}

因为对于 Node 你已经将 IShallowCloneable<Node> 实现为 explicit interface,所以它只有在你转换为它时才会起作用:

// prints Node
Console.WriteLine(((IShallowCloneable<Node>)node).ShallowClone().GetType().Name); 

如果你想让它表现得像 Point3D 你需要像你在那里那样实现它(用 new 关键字隐藏继承的 Point2D 实现)。

因此,如果您想在不更改的情况下显式使用 ShallowClone 方法 Class

var node = new Node(1, 0, 0, 0);
var node2 = ((IShallowCloneable<Node>)node).ShallowClone();

或者如果你想要隐式实现,你必须像这样 Class 修改 Node Class 中的 ShallowClone() 方法实现

new public Node ShallowClone()
{
    return new Node(Id, X, Y, Z);
}

其他参考资料

C# Interfaces. Implicit implementation versus Explicit implementation