无法通过基本类型的变量作为输出参数? [英] Can't pass variables of base types as out parameters?

查看:138
本文介绍了无法通过基本类型的变量作为输出参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只注意到这不起作用:

  VAR字典=新词典< INT,的XElement>(); 
XContainer元素;
// ...
如果(dict.TryGetValue(IDX,出元素)){// ...

然后我尝试这样的:

 类A {} 
b类: A {}

类节目{
静态无效的主要(){
A A;
A =惩戒(); //没有错误,确定
参考(REF A); //编译器错误,确定...
OUT(出); //编译器错误,lolwut?
}
静态乙惩戒(){返回NULL; }
静态无效的参考(REF B B){}
静态无效输出(输出B B){B = NULL; }
}



我为什么会在最后一次调用编译器错误?



修改确定,所以当我从答案出理解为变相的裁判,因此它可以共享和其它功能改变或线程。不过说真的,是不是'出来'应该是从一个函数返回多个值的方法吗?因为如果是这样,它似乎并不擅长的。 如果共享产生的问题,那么不共享。只要创建在函数的开始一个隐藏的变量,并使用它。我的意思是:



 静态无效输出(输出B B){$ B $条b B bHidden; //编译器生成; 
//所有到B的引用将被替换为bHidden;
B = bHidden;
}

是否有任何理由不能做到这样?现在看来安全,我...


解决方案

我在回答出理解是伪装的参考,因此它可以由其它功能或线程共享和改变。不过说真的,是不是'出来'应该是从一个函数返回多个值的方法吗?因为如果是这样,它似乎并不擅长的。如果共享造成了问题,那就不要分享。刚创建的功能的开始的隐藏变量,并使用它。我的意思是:




 静态无效输出(输出B B)
{$ B $条b b bHidden; //编译器生成;
//所有到B的引用将被替换为bHidden;
B = bHidden;
}




是否有任何理由不能这样做的方法吗?现在看来安全,我...




这样的系统被称为复制淘汰制,原因显而易见。它可以做的方式,但这样做会创建自己的有趣的问题。例如:

 无效M()
{
INT B = 1;

{
N(OUT B);
}
赶上(FooException)
{
Console.WriteLine(B);
}
}

无效N(OUT INT C)
{
C = 123;
P();
C = 456;
}

无效P()
{
抛出新FooException();
}



有什么程序的输出?什么?它应该是



下一个问题是:你想出来的行为是一致的或不符合裁判?如果你希望它是不一致的,那么恭喜你,你只是增加了一个非常混乱不一致的语言。如果你希望它是一致的,那么你需要让裁判用副本复印件去的语义,它引入了一些它自己的问题,无论是在性能方面和正确性的条款。



我可以去整天列举参考语义和复制语义之间的差异,但我不会。我们已经有了这个系统,我们已经得到了,所以要学会与它的工作系统中。



除此之外,如果你想从一个返回多个值方法,不使用out参数即可。这可能是在2001年做聪明的事情,但它是2012年了,我们在您的处置有更多的工具。如果你想返回两个值:




  • 返回一个元组

  • 中的代码为两个方法重构每个返回一个值

  • 如果两个值是值类型和一个布尔值,返回一个空值类型。


Just noticed this doesn't work:

var dict = new Dictionary<int, XElement>();
XContainer element;
//...
if (dict.TryGetValue(idx, out element)) { //...

Then I tried this:

class A { }
class B : A { }

class Program {
    static void Main() {
        A a;
        a = Ret();  // no error, ok
        Ref(ref a); // compiler error, ok...
        Out(out a); // compiler error, lolwut?!
    }
    static B Ret() { return null; }
    static void Ref(ref B b) { }
    static void Out(out B b) { b = null; }
}

Why do I get a compiler error in the last call?

Edit: Ok, so as I understand from the answers 'out' is 'ref' in disguise, so it can be shared and changed by other functions or threads. But really, isn't 'out' supposed to be a way to return multiple values from a function? Because if so, it doesn't seem to be good at it. If sharing creates problems, then don't share. Just create a hidden variable at the start of the function, and work with it. I mean:

static void Out(out B b) {
    B bHidden; // compiler generated;
        // all references to b are replaced with bHidden;
    b = bHidden;
}

Is there any reason it can't be done this way? It seems safe to me now...

解决方案

as I understand from the answers 'out' is 'ref' in disguise, so it can be shared and changed by other functions or threads. But really, isn't 'out' supposed to be a way to return multiple values from a function? Because if so, it doesn't seem to be good at it. If sharing creates problems, then don't share. Just create a hidden variable at the start of the function, and work with it. I mean:

static void Out(out B b) 
{     
    B bHidden; // compiler generated;
               // all references to b are replaced with bHidden;
    b = bHidden; 
} 

Is there any reason it can't be done this way? It seems safe to me now...

Such a system is called a "copy out" system, for obvious reasons. It could be done that way, but doing so creates interesting problems of its own. For example:

void M()
{
    int b = 1;
    try
    { 
        N(out b);
    }
    catch (FooException)
    {
        Console.WriteLine(b);
    }
}

void N(out int c)
{
    c = 123;
    P();
    c = 456;
}

void P()
{
    throw new FooException();
}

What is the output of the program? What should it be?

Next problem: Do you want out's behaviour to be consistent or inconsistent with ref? If you want it to be inconsistent, then congratulations, you just added a highly confusing inconsistency to the language. If you want it to be consistent then you need to make ref use "copy in copy out" semantics, which introduces a number of problems of its own, both in terms of performance and in terms of correctness.

I could go on all day enumerating the differences between reference semantics and copy semantics, but I won't. The system we've got is the system we've got, so learn to work with it.

And besides, if you want to return more than one value from a method, don't use an out parameter. That might have been the smart thing to do in 2001, but it is 2012 now and we have more tools at your disposal. If you want to return two values:

  • return a tuple
  • refactor the code into two methods that each return one value
  • if the two values are a value type and a bool, return a nullable value type.

这篇关于无法通过基本类型的变量作为输出参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆