我们刚刚在代码中找到了这些:
public static class ObjectContextExtensions
{
public static T Find<T>(this ObjectSet<T> set, int id, params Expression<Func<T, object>>[] includes) where T : class
{
...
}
public static T Find<T>(this ObjectSet<T> set, int id, params string[] includes) where T : class
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,除了params.之外,它们具有相同的签名.
它们被用于多种方式,其中之一:
DBContext.Users.Find(userid.Value); //userid being an int? (Nullable<int>)
Run Code Online (Sandbox Code Playgroud)
对我来说奇怪的是,它解决了第一次超载.
Q1:为什么这不会产生编译错误?
Q2:为什么C#编译器将上述调用解析为第一种方法?
编辑:只是为了澄清,这是C#4.0,.Net 4.0,Visual Studio 2010.
我最近发现了一个有趣的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我不认为提供这种模糊的界面是好的,不建议这样做,但遗产是遗留的,必须保持:)