Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解决",;“最衍生的”;虚拟重写中的方法_C#_Overriding_Virtual Functions - Fatal编程技术网

C# 解决",;“最衍生的”;虚拟重写中的方法

C# 解决",;“最衍生的”;虚拟重写中的方法,c#,overriding,virtual-functions,C#,Overriding,Virtual Functions,我有一个简单的基类和派生类: class Base { public virtual void Write(int value) { Console.WriteLine("base int: {0}", value); } public virtual void Write(string value) { Console.WriteLine("base string: {0}", value); } } clas

我有一个简单的基类和派生类:

class Base
{
    public virtual void Write(int value)
    {
        Console.WriteLine("base int: {0}", value);
    }

    public virtual void Write(string value)
    {
        Console.WriteLine("base string: {0}", value);
    }
}

class Derived : Base
{
    public override void Write(int value)
    {
        Console.WriteLine("derived int: {0}", value);
    }

    public virtual void Write(IEnumerable enumerable)
    {
        Console.WriteLine("derived IEnumerable: {0}", enumerable);
    }

    public virtual void Write(object o)
    {
        Console.WriteLine("derived obj: {0}", o);
    }
}
如果我运行这个:

    static void Main(string[] args)
    {
        Derived d = new Derived();
        Console.WriteLine("derived:");
        d.Write(42);
        d.Write("hello");

        Console.WriteLine("base:");
        Base b = d;
        b.Write(42);
        b.Write("hello");
    }
我得到:

derived:
derived obj: 42
derived IEnumerable: hello
base:
derived int: 42
base string: hello
但我希望“b.Write(42)”和“d.Write(42)”是相同的。字符串大小写也是如此

我不明白什么?在我无法修改“Base”的约束条件下,我如何才能使行为成为我期望的行为


更新:请参阅。

字符串可以隐式转换为IEnumerable(字符),但其ToString()仍返回字符串。因此,
b.Write(“hello”)
正在解析IEnumerable虚拟方法,因为它更接近引用的类型

我将进行验证,但如果您在派生类中重写字符串重载,它可能会在客户端代码中正确解析

编辑

我错了,凌驾于此无济于事。您可能必须重命名派生的虚拟对象以避免冲突

编辑II

下面的内容确实有用,但它是uber hackey,我不喜欢它。将此方法添加到导出的

public new void Write(string value)
{
    base.Write(value);
}

字符串可以隐式转换为IEnumerable(字符数),但其ToString()仍返回字符串。因此,
b.Write(“hello”)
正在解析IEnumerable虚拟方法,因为它更接近引用的类型

我将进行验证,但如果您在派生类中重写字符串重载,它可能会在客户端代码中正确解析

编辑

我错了,凌驾于此无济于事。您可能必须重命名派生的虚拟对象以避免冲突

编辑II

下面的内容确实有用,但它是uber hackey,我不喜欢它。将此方法添加到导出的

public new void Write(string value)
{
    base.Write(value);
}
之所以会出现这种情况,是因为C#首先考虑在类型中声明的方法,包括重写方法。请参阅:

这很好地解释了这一点,也解释了原因

以下两条规则证明了这种高度不直观的行为的合理性:

  • 方法是否被重写是一个实现细节 这应该被允许改变 不破坏客户端代码
  • 对基类的更改如果不破坏继承的类,则应 不中断继承的客户端 班级
  • 之所以会出现这种情况,是因为C#首先考虑在类型中声明的方法,包括重写方法。请参阅:

    这很好地解释了这一点,也解释了原因

    以下两条规则证明了这种高度不直观的行为的合理性:

  • 方法是否被重写是一个实现细节 这应该被允许改变 不破坏客户端代码
  • 对基类的更改如果不破坏继承的类,则应 不中断继承的客户端 班级

  • 你到底在执行什么来获得你所说的输出?我无意中没有在第一个版本中包括它,但它在这个版本中。你到底在执行什么来获得你所说的输出?我无意中没有在第一个版本中包括它,但它在这个版本中。到的间接链接很有用。我想没有办法改变这段代码来做我想做的事?我唯一能想到的就是将Write(object o)改为WriteObject(object o),但这很难看。更好的解释是在指向的间接链接中。我想没有办法改变这段代码来做我想做的事?我唯一能想到的是将Write(object o)改为WriteObject(object o),但这很难看。更好的解释是,在Write(int)的情况下,我根本不希望调用基。在Write(int)的情况下,我根本不希望调用基。