为什么不支持C#引用的回报?不支持

由网友(久爱而不腻,深爱而不弃)分享简介:我已阅读,.NET支持的回报引用,但C#不。是否有特别的原因吗?为什么我不能做这样的事情:静态参考INT MAX(REF INT X,REF int y)对{如果(X> Y)返回REF X;其他返回裁判ÿ;}解决方案 更​​新:这个问题是的我的博客上2011年6月23日。感谢伟大的问题!您是正确的; .NET...

我已阅读,.NET支持的回报引用,但C#不。是否有特别的原因吗?为什么我不能做这样的事情:

 静态参考INT MAX(REF INT X,REF int y)对
{
  如果(X> Y)
    返回REF X;
  其他
    返回裁判ÿ;
}
 

解决方案

更​​新:这个问题是的我的博客上2011年6月23日。感谢伟大的问题!

您是正确的; .NET不支持的中的方法返回托管引用变量。 .NET还支持局部变量包含托管引用其他变量。 (但是请注意,.NET不支持的字段或阵列包含托管引用其他变量,因为过于复杂的垃圾收集故事。另外,管理引用变量类型的无法转换为对象,因此可能不能用作类型参数的泛型类型或方法。)

批评家RPM1984出于某种原因,要求传票,这一事实。 RPM1984我建议您阅读的CLI规范分区我​​第8.2.1.1节,管理的指针和相关类型有关.NET的此功能的信息。

这是完全有可能创建一个版本的C#同时支持这些功能。然后,你可以做这样的事情

 静态参考INT MAX(REF INT X,REF int y)对
{
  如果(X> Y)
    返回REF X;
  其他
    返回裁判ÿ;
}
 
在visual Studio上使用C 调用非托管C 生成的DLL文件 图文讲解

然后用

叫它

  INT A = 123;
INT B = 456;
REF INT C = REF MAX(REF A,参考B);
C + = 100;
Console.WriteLine(B); // 556!
 

我知道经验,有可能建立一个版本的C#支持这些功能的,因为我已经这样做了的。高级程序员,尤其是人移植托管C ++ code,经常要求我们提供更多的C ++ - 那样的能力做事的引用,而无需离开实际使用指针和寄托记忆所有的地方的大铁锤。通过使用托管引用您获得这些好处无需支付搞砸了你的垃圾收集的性能为代价。

我们已经考虑过这个功能,而实际执行它足以显示给其他内部团队,以获得他们的反馈。然而,在这个时候根据我们的研究我们相信该功能不具有足够广泛的吸引力和说服力的使用情况,使之成为一个真正支持的语言功能。我们有其他更高的优先级,并在有限的时间和精力提供量,所以我们不打算做这个功能,任何时间很快。

另外,适当做这将需要一些改变CLR。眼下CLR对待裁判返回方法作为的法律的,但是的无法证实的,因为我们没有一个检测器检测到这种情况:

  REF INT M1(REF INT X)
{
    返回REF X;
}

REF INT M2()
{
    INT Y = 123;
    返回参考货币供应量M1(REF Y); // 麻烦!
}

INT M3()
{
    REF INT Z = REF M2();
    返回Z者除外;
}
 

M3返回M2的局部变量的内容,但该变量的生存期已经结束!它可以编写一个检测器,用于确定裁判,收益的使用,明确做的没有的违反了堆的安全性。我们会做的是写这样的检测,如果检测不能证明堆栈的安全,那么我们不会允许在程序的那部分参考收益的使用情况。它不是一个大量的开发工作,这样做,但它是一个很大的测试团队的负担,以确保我们真正得到了所有的情况。这只是另一件事,增加该功能的地步,现在的收益不超过成本费用。

如果您能描述我为什么是你要这个功能,我真的AP preciate了。信息越多,我们必须从真正的客户,为什么自己想吧,就越有可能将使它进入产品一天。这是一个可爱的小功能,我希望能够得到它的客户在某种程度上,如果有足够的兴趣。

(另见相关的问题Is它可以返回一个引用到变量在C#?和Can我使用引用一个C#函数,如C ++?)

里面

I have read that .NET supports return of references, but C# doesn't. Is there a special reason? Why I can't do something like:

static ref int Max(ref int x, ref int y) 
{ 
  if (x > y) 
    return ref x; 
  else 
    return ref y; 
} 

解决方案

UPDATE: This question was the subject of my blog on June 23rd 2011. Thanks for the great question!

You are correct; .NET does support methods that return managed references to variables. .NET also supports local variables that contain managed references to other variables. (Note however that .NET does not support fields or arrays that contain managed references to other variables because that overly complicates the garbage collection story. Also the "managed reference to variable" types are not convertible to object, and therefore may not be used as type arguments to generic types or methods.)

Commenter "RPM1984" for some reason asked for a citation for this fact. RPM1984 I encourage you to read the CLI specification Partition I Section 8.2.1.1, "Managed pointers and related types" for information about this feature of .NET.

It is entirely possible to create a version of C# which supports both these features. You could then do things like

static ref int Max(ref int x, ref int y) 
{ 
  if (x > y) 
    return ref x; 
  else 
    return ref y; 
} 

and then call it with

int a = 123;
int b = 456; 
ref int c = ref Max(ref a, ref b); 
c += 100;
Console.WriteLine(b); // 556!

I know empirically that it is possible to build a version of C# that supports these features because I have done so. Advanced programmers, particularly people porting unmanaged C++ code, often ask us for more C++-like ability to do things with references without having to get out the big hammer of actually using pointers and pinning memory all over the place. By using managed references you get these benefits without paying the cost of screwing up your garbage collection performance.

We have considered this feature, and actually implemented enough of it to show to other internal teams to get their feedback. However at this time based on our research we believe that the feature does not have broad enough appeal or compelling usage cases to make it into a real supported language feature. We have other higher priorities and a limited amount of time and effort available, so we're not going to do this feature any time soon.

Also, doing it properly would require some changes to the CLR. Right now the CLR treats ref-returning methods as legal but unverifiable because we do not have a detector that detects this situation:

ref int M1(ref int x)
{
    return ref x;
}

ref int M2()
{
    int y = 123;
    return ref M1(ref y); // Trouble!
}

int M3()
{
    ref int z = ref M2();
    return z;
}

M3 returns the contents of M2's local variable, but the lifetime of that variable has ended! It is possible to write a detector that determines uses of ref-returns that clearly do not violate stack safety. What we would do is write such a detector, and if the detector could not prove stack safety, then we would not allow the usage of ref returns in that part of the program. It is not a huge amount of dev work to do so, but it is a lot of burden on the testing teams to make sure that we've really got all the cases. It's just another thing that increases the cost of the feature to the point where right now the benefits do not outweigh the costs.

If you can describe for me why it is you want this feature, I would really appreciate that. The more information we have from real customers about why they want it, the more likely it will make it into the product someday. It's a cute little feature and I'd like to be able to get it to customers somehow if there is sufficient interest.

(See also related questions Is it Possible to Return a Reference to a Variable in C#? and Can I use a reference inside a C# function like C++?)

阅读全文

相关推荐

最新文章