相关疑难解决方法(0)

C#方法覆盖了解决方案的怪异

请考虑以下代码段:

using System;

class Base
{
    public virtual void Foo(int x)
    {
        Console.WriteLine("Base.Foo(int)");
    }
}

class Derived : Base
{
    public override void Foo(int x)
    {
        Console.WriteLine("Derived.Foo(int)");
    }

    public void Foo(object o)
    {
        Console.WriteLine("Derived.Foo(object)");
    }
}

public class Program
{
    public static void Main()
    {
        Derived d = new Derived();
        int i = 10;
        d.Foo(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

令人惊讶的输出是:

Derived.Foo(object)
Run Code Online (Sandbox Code Playgroud)

我希望它能够选择被覆盖的Foo(int x)方法,因为它更具体.但是,C#编译器会选择非继承Foo(object o)版本.这也导致拳击操作.

这种行为的原因是什么?

c# inheritance overriding

25
推荐指数
2
解决办法
1015
查看次数

重载分辨率和虚拟方法

考虑以下代码(它有点长,但希望你可以遵循):

class A
{
}

class B : A
{
}

class C
{
    public virtual void Foo(B b)
    {
        Console.WriteLine("base.Foo(B)");
    }
}

class D: C
{
    public override void Foo(B b)
    {
        Console.WriteLine("Foo(B)");
    }

    public void Foo(A a)
    {
        Console.WriteLine("Foo(A)");
    }
}

class Program
{
    public static void Main()
    {
        B b = new B();
        D d = new D ();
        d.Foo(b);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你认为这个程序的输出是"Foo(B)"那么你和我在同一条船上:完全错了!事实上,它输出"Foo(A)"

如果我从C类中删除虚方法,那么它按预期工作:"Foo(B)"是输出.

为什么编译器选择带有Awhen 的版本B是派生得更多的类?

c# virtual-functions overload-resolution

22
推荐指数
2
解决办法
2230
查看次数

编译器值类型分辨率和硬编码"0"整数值

首先,有点背景.阅读此处发布的问题和已接受的答案,以了解我的问题的具体方案.我不确定是否存在其他相似的案例,但这是我所知道的唯一案例.

上面的"怪癖"是我早已意识到的.直到最近,我才明白原因的全面性.

微软关于这个SqlParameter课程的文档对这种情况有了更多的了解.

Object在value参数中指定a 时,SqlDbType将从Object的Microsoft .NET Framework类型推断出.

使用SqlParameter构造函数的此重载指定整数参数值时请小心.因为此重载采用type的值Object,所以必须在值为零时将整数值转换为Object 类型,如下面的C#示例所示.

Parameter = new SqlParameter("@pname", Convert.ToInt32(0));

如果不执行此转换,编译器会假定您尝试调用SqlParameter(string,SqlDbType)构造函数重载.

(emph.补充)

我的问题是为什么编译器假设当你指定硬编码"0"(并且只有值"0")时,你试图指定枚举类型而不是整数类型?在这种情况下,它假定您声明SqlDbType值,而不是值0.

这是非直观的,更糟糕​​的是,错误是不一致的.我有一些旧的应用程序,我已经编写了多年来调用存储过程.我将对应用程序进行更改(通常甚至与我的SQL Server类无关),发布更新,这个问题会突然中断应用程序.

当包含多个方法签名的对象包含两个相似的签名时,为什么编译器会被值0混淆,其中一个参数是对象/整数而另一个接受枚举?

正如我所提到的,我从未将其视为任何其他类的任何其他构造函数或方法的问题.这是SqlParameter该类的独特之处还是这是一个在C#/ .Net中继承的bug?

.net c# compiler-construction

18
推荐指数
2
解决办法
1197
查看次数

C#语言设计的支柱

文章(http://www.artima.com/intv/nonvirtualP.html)中,Anders Hejlsberg提到版本控制是C#语言设计的支柱之一.有谁知道其他支柱是什么?

c# language-design

4
推荐指数
1
解决办法
549
查看次数