这个完整的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,我追溯到这个调用模式,我试图将调用转发给更具体的重载.令我惊讶的是,调用并没有选择更具体的重载,而是回调自身.它显然与基类型是通用的有关,但我不明白为什么它不会选择执行(字符串)重载.
有没有人对此有任何见解?
上面的代码被简化为显示模式,实际结构有点复杂,但问题是一样的.
在最近重构了一些涉及一些类重命名的代码之后,我的一些代码以惊人的方式破解了.原因是失败的"是"运算符测试,我很惊讶不是编译器错误或警告.
完整的程序显示了这种情况:
static class ExtensionMethods {}
class Program {
static void Main() {
Test("Test");
}
public static bool Test(object obj)
{
return obj is ExtensionMethods;
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于ExtensionMethods是一个静态类,我本来期望"obj是ExtensionMethods"来引发某种警告.
例如,当被测对象永远不能是提供的类型时,编译器将为"is"运算符发出警告((string)obj) is System.Uri
.
我是否忘记了这实际上是一个有意义的测试的场景?
.net十进制值1m和1.0000m之间是否存在实际差异?
内部存储是不同的:
1m : 0x00000001 0x00000000 0x00000000 0x00000000
1.0000m : 0x000186a0 0x00000000 0x00000000 0x00050000
Run Code Online (Sandbox Code Playgroud)
但是,BCL中的方法是否会使用"有效数字"的知识呢?
我问,因为我正在努力压缩磁盘存储或网络传输的十进制值所需的空间,并且在我存储它之前想要"规范化"该值以提高它的可压缩性.但是,我想知道它是否可能导致问题.我猜它应该没问题,但只是因为我没有看到任何暴露值的精度的方法或属性.有没有人知道呢?
说我有一个简单的(最简单的?)C#程序:
class Program {
static void Main() {
System.Console.WriteLine("Hello, world");
}
}
Run Code Online (Sandbox Code Playgroud)
如果,我编译该代码并查看生成的.exe,我按预期在exe图像中看到"Hello,world"字符串.
如果我重构代码:
class Program {
const string Greeting = "Hello, world";
static void Main() {
System.Console.WriteLine(Greeting);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我编译该代码并查看生成的.exe,我会在exe映像中看到两次"Hello,world"字符串文字.这对我来说很惊讶.我的印象是字符串文字是共享的,因此它只会出现在图像中一次.有谁能解释一下?也许反射元数据需要第二个字符串副本?
我试图找出powershell如何解析名称,但我似乎无法找到任何信息.
这是场景:
存在可执行文件:
c:\stuff\log.exe
Run Code Online (Sandbox Code Playgroud)
路径设置如此 $env:path = 'c:\stuff\'
我加载了一个模块,其中包含一个函数名称"log"和一个别名为"log"的二进制cmdlet.
当我在命令行中键入"log"时,PowerShell如何决定是执行c:\ stuff\log.exe还是函数名称日志,还是将cmdlet作为日志执行?
从实验来看,分辨率顺序似乎是:Cmdlet函数在路径上可执行
但我找不到任何记录这件事的东西.
下面是一个示例PowerShell脚本(它不起作用),它说明了我想要做的事情:
$BuildRoot = '_Provided from script parameter_'
$Files = 'a.dll', 'b.dll', 'c.dll'
$BuiltFiles = $Files | Join-Path $BuildRoot
Run Code Online (Sandbox Code Playgroud)
我有一个文件名列表和一个目录名,我想把它们加在一起,很简单.问题是这不起作用,因为Join-Path
参数-ChildPath
接受来自管道ByPropertyName的输入,因此报告以下错误:
输入对象不能绑定到命令的任何参数,因为该命令不接受管道输入或输入及其属性与任何接受管道输入的参数不匹配.
我可以通过将行更改为以下内容来"修复"它:
$BuiltFiles = $Files | Select @{ Name = "ChildPath"; Expression = {$_}} | join-path $BuildRoot
Run Code Online (Sandbox Code Playgroud)
基本上,select
操作是将对象转换为属性值.这有效,但它引入了很多语法噪音来完成看似微不足道的事情.如果这是唯一的方法,那就这样吧,但是我想让这个脚本在将来可以维护,而且乍一看这有点难以理解.
有没有更清洁的方法来完成我在这里尝试做的事情?
通常,对于value(struct)类型,与null(或对象类型)的比较将导致编译器错误.
struct Value
{
}
class Program
{
static void Main()
{
object o = new object();
Value v = default;
// Error CS0019 Operator '==' cannot be applied to operands of type 'Value' and '<null>'
var a = v == null;
// Error CS0019 Operator '==' cannot be applied to operands of type 'Value' and 'object'
var b = v == o;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我在结构上添加相等运算符重载,则与null的比较不再产生编译器错误:
struct Value
{
public static bool operator ==(Value l, Value r)
{
return true; …
Run Code Online (Sandbox Code Playgroud) ..如果是的话,这是什么行为?我在最近看到的一些代码中遇到了这个问题,这对我来说非常困惑.我没有java编译器,所以我不能轻易回答这个问题.这是我所说的粗略的例子.我希望这个结果出现编译错误,但据我所知,它来自一个正常工作的代码库.
abstract class Base {
...
abstract boolean foo(String arg);
}
class Sub extends Base {
...
boolean foo(String arg) {
if(condition)
return true;
else
return super.foo(arg); //<-- <boggle/>
}
}
Run Code Online (Sandbox Code Playgroud) 说我有一个相当昂贵的断言:
bool IsCompatible(Object x, Object y) {
// do expensive stuff here
}
Run Code Online (Sandbox Code Playgroud)
如果我用以下方法测试这个断言:
Debug.Assert(IsCompatible(x,y));
Run Code Online (Sandbox Code Playgroud)
IsCompatible是否会在发布版本中执行?
我的理解是Debug.Assert被标记为[Conditional("DEBUG")],对它的调用只会在调试版本中发出.我认为这不会阻止表达式在发布模式下进行评估,因为方法调用可能有副作用,只会将结果传递给Debug.Assert.那是对的吗?
我应该这样做:
#if DEBUG
Debug.Assert(IsCompatible(x,y));
#endif
Run Code Online (Sandbox Code Playgroud)
为了确保我不在发布模式下支付IsCompatible的费用?
我理解HEAD请求是什么,以及它可以用于什么.任何标准的现代浏览器都会发送HEAD请求吗?如果是这样,在什么情况下呢?