Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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#匿名类型'ToString'复杂吗?_C#_.net_.net Core_Roslyn_Anonymous Types - Fatal编程技术网

C#匿名类型'ToString'复杂吗?

C#匿名类型'ToString'复杂吗?,c#,.net,.net-core,roslyn,anonymous-types,C#,.net,.net Core,Roslyn,Anonymous Types,有人知道为什么C中的匿名类型使用如此复杂的ToString实现吗?我相信早期版本使用了更简单的StringBuilder实现 以下是ILSpy提供的示例ToString: public override string ToString() { object[] array = new object[2]; <a>j__TPar val = <a>i__Field; ref <a>j__TPar reference = ref val;

有人知道为什么C中的匿名类型使用如此复杂的
ToString
实现吗?我相信早期版本使用了更简单的
StringBuilder
实现

以下是ILSpy提供的示例
ToString

public override string ToString() {
    object[] array = new object[2];
    <a>j__TPar val = <a>i__Field;
    ref <a>j__TPar reference = ref val;
    <a>j__TPar val2 = default(<a>j__TPar);
    object obj;
    if (val2 == null) {
        val2 = reference;
        reference = ref val2;
        if (val2 == null) {
            obj = null;
            goto IL_0046;
        }
    }
    obj = reference.ToString();
    goto IL_0046;
    IL_0046:
    array[0] = obj;
    <b>j__TPar val3 = <b>i__Field;
    ref <b>j__TPar reference2 = ref val3;
    <b>j__TPar val4 = default(<b>j__TPar);
    object obj2;
    if (val4 == null) {
        val4 = reference2;
        reference2 = ref val4;
        if (val4 == null) {
            obj2 = null;
            goto IL_0081;
        }
    }
    obj2 = reference2.ToString();
    goto IL_0081;
    IL_0081:
    array[1] = obj2;
    return string.Format(null, "{{ a = {0}, b = {1} }}", array);
}
public重写字符串ToString(){
object[]数组=新对象[2];
j_uutpar val=i_u字段;
参考j_uutpar参考=参考值;
j_uutpar val2=默认值(j_utpar);
对象对象对象;
if(val2==null){
val2=参考;
参考=参考值2;
if(val2==null){
obj=null;
goto IL_0046;
}
}
obj=reference.ToString();
goto IL_0046;
IL_0046:
数组[0]=obj;
j_uutpar val3=i_u字段;
参考j_u_utpar reference2=参考值3;
j_uutpar val4=默认值(j_utpar);
对象obj2;
if(val4==null){
val4=参考2;
参考2=参考值4;
if(val4==null){
obj2=null;
goto IL_0081;
}
}
obj2=reference2.ToString();
goto IL_0081;
IL_0081:
数组[1]=obj2;
返回string.Format(null,“{a={0},b={1}”,数组);
}
查看Roslyn编译器从一开始就通过
string.Format
实现。我不知道为什么它是以这种方式实现的。因为它是编译器,所以我假设性能和可维护性的原因已经考虑在内(而不是生成代码的简单性)。虽然Format内部似乎使用了
StringBuilder
,但不会说以前的实现较慢或较快

UPD

似乎在
Roslyn
引入之前,编译器真正生成了
StrinBuilder
实现。来自Andrew Troelsen的Pro C#2008和.NET 3.5平台:

所有匿名类型都自动从System.Object派生,并随重写版本的Equals()、GetHashCode()和ToString()一起提供。ToString()实现只是从每个名称/值对构建一个字符串,例如:

public重写字符串ToString()
{
StringBuilder=新建StringBuilder();builder.Append(“{Color=”);
builder.Append(这个.i__字段);builder.Append(“,Make=”);
builder.Append(此.i__字段);builder.Append(“,CurrentSpeed=”);
builder.Append(这个.i__字段);builder.Append(“}”);
返回builder.ToString();
}
我已经写过(不知道它有多正确=),而且旧的实现似乎更快

在github()上还发现了一个问题,除其他事项外,它引起了人们对
ToString
性能的关注,但在评论中提出了一个有效的问题:

对ToString表示使用匿名类型是否常见?我怀疑大多数人会不会打电话给ToString来了解其中一个。它们将被传递给序列化程序,序列化程序将执行不同的表示或用作LINQ中的分组键


我强烈不同意这是基于意见的,但这对你来说是多余的。有人知道所讨论的实际情况,甚至可能会有Github问题解释或提交来解释更改……每当
?。
运算符应用于无约束类型参数时,C#编译器就会生成带有ref赋值的奇怪代码模式@Daniel谢谢,但我想知道这个模式的理由是什么。由于问题不幸地结束了,我将给你一个接近正确的答案。我确实看到了github的问题,但我认为这与为什么
ToString
变得如此复杂无关,尽管我开始相信这可能是为了最小化装箱和/或帮助JIT在运行时为具体类型构造方法时进行优化。顺便说一句,你所说的“责备”是什么意思?@NetMage谢谢。简单的怪罪。
public override string ToString()
{
    StringBuilder builder = new StringBuilder(); builder.Append("{ Color = "); 
    builder.Append(this.<Color>i__Field); builder.Append(", Make = "); 
    builder.Append(this.<Make>i__Field); builder.Append(", CurrentSpeed = "); 
    builder.Append(this.<CurrentSpeed>i__Field); builder.Append(" }");
    return builder.ToString();
}