相关疑难解决方法(0)

C#方法重载决策没有选择具体的通用覆盖

这个完整的C#程序说明了这个问题:

public abstract class Executor<T>
{
    public abstract void Execute(T item);
}

class StringExecutor : Executor<string>
{
    public void Execute(object item)
    {
        // why does this method call back into itself instead of binding
        // to the more specific "string" overload.
        this.Execute((string)item);
    }

    public override void Execute(string item) { }
}

class Program
{
    static void Main(string[] args)
    {
        object item = "value";
        new StringExecutor()
            // stack overflow
            .Execute(item); 
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到了一个StackOverlowException,我追溯到这个调用模式,我试图将调用转发给更具体的重载.令我惊讶的是,调用并没有选择更具体的重载,而是回调自身.它显然与基类型是通用的有关,但我不明白为什么它不会选择执行(字符串)重载.

有没有人对此有任何见解?

上面的代码被简化为显示模式,实际结构有点复杂,但问题是一样的.

c# generics overload-resolution

45
推荐指数
3
解决办法
2309
查看次数

模糊方法重载

这个问题再次引起了我的兴趣.有人可以提供技术解释,说明为什么以下代码不会产生任何警告或错误.你必须问自己的问题(当然)你感到幸运吗?

class Program
{
    static string Feeling(object o) { return "Lucky"; }
    static string Feeling(string s) { return "Unlucky"; }

    static void Main(string[] args)
    {
        Console.WriteLine("I feel " + Feeling(null));
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您知道在运行代码的情况下将调用哪种方法,则会获得奖励积分.只是为了添加侮辱,它不仅仅发生在null参数:

class Program
{
    static string Feeling(int i) { return "Lucky"; }
    static string Feeling(uint i) { return "Unlucky"; }

    static void Main(string[] args)
    {
        Console.WriteLine("I feel " + Feeling(7));
    }
}
Run Code Online (Sandbox Code Playgroud)

c# overloading

6
推荐指数
1
解决办法
2252
查看次数

选择看起来像错误/缺失功能的重载时,奇怪的C#编译器行为

我最近发现了一个有趣的C#编译器行为.想象一下这样的界面:

public interface ILogger
{
   void Info(string operation, string details = null);
   void Info(string operation, object details = null);
}
Run Code Online (Sandbox Code Playgroud)

如果我们这样做

logger.Info("Create")
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨他不知道选择哪个重载(不明确的调用......).似乎合乎逻辑,但是当你尝试这样做时:

logger.Info("Create", null)
Run Code Online (Sandbox Code Playgroud)

它突然没有麻烦,搞清楚null是一个字符串.此外,似乎找到正确的重载的行为已经随着时间的推移而改变,我发现旧代码中的错误在之前工作并且停止工作,因为编译器决定使用另一个重载.

所以我真的很想知道为什么C#在第二种情况下不会像第一种情况那样产生相同的错误.这样做似乎非常符合逻辑,但它尝试将其解析为随机重载.

PS我不认为提供这种模糊的界面是好的,不建议这样做,但遗产是遗留的,必须保持:)

c# overloading compiler-errors

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

为什么编译器选择通用方法而不是特定方法?

我有这个服务接口。

public interface IService
{
    Task SetAsync(string key, string value, TimeSpan? expiration = null);
    Task SetAsync<T>(string applicationName, string key, T value, TimeSpan? expiration = null);
}
Run Code Online (Sandbox Code Playgroud)

我想通过这样做来调用第一种方法。

service.SetAsync("Key", "Value", TimeSpan.FromMinutes(1));
Run Code Online (Sandbox Code Playgroud)

方法调用与第一个方法的契约 100% 匹配。然而编译器通过假设TimeSpan是我的泛型类型来选择第二种方法。

为什么会这样?

.net c# generics

3
推荐指数
1
解决办法
124
查看次数