2016-11-07 57 views
-1
private static void Foo(Exception e) 
{ 
    e = new Exception("msg1"); 
} 

static void Main(string[] args) 
{ 
    try 
    { 
    int zero = 0; 
    int ecks = 1/zero; 
    } 
    catch (Exception e) 
    { 
    // I thought Exception is passed by reference, therefore Foo changes e to 
    // point to new Exception instance with message "msg1". 
    // But it stays the same 
    Foo(e); 
    throw e; 
    } 
} 

它适用于类向方法传递例外

public class MyClass 
{ 
    public string Name { get; set; } 
} 

private static void Foo(MyClass m) { m.Name = "bar"; } 

static void Main(string[] args) 
{ 
    Voda v = new Voda(); 
    v.Name = "name"; 
    Foo(v); // v.Name gets value "bar" 
} 

根据msdn例外是类。

编辑

private static void Foo(Exception e) 
{ 
    while (e != null && e.InnerException != null) 
    { 
    // I'm changing where e points. 
    // Therefore caller Exception should now point to most inner exception 
    e = e.InnerException; 
    }); 
} 
+1

使用ref关键字:无效美孚(REF例外五) – Evk

+2

除非你使用'ref', C#中没有任何内容是通过引用传递的。对于参考类型,数据的_reference_被复制到方法中。所以你可以改变对象(如果它是可变的),但你不能在调用方法中改变变量 – MAV

+1

不是真的重复,但[看看](http://stackoverflow.com/q/186891/1997232)。 – Sinatr

回答

1

当你调用方法Foo(e)e的参考副本被传递到Exception e这样既原始eException e指向相同的位置。然后您更改Exception e中的引用,并指向其他一些异常。但原始e中的参考仍保持不变,因为它是“按值传递”而不是“通过参考传递”的情况。

+0

但是异常是类,它不是像整型或布尔型的原始类型。异常是特殊的,它通过价值传递。 – broadband

+0

您需要明白,引用变量也存储在程序堆栈中,就像基本类型一样。但区别在于引用变量指向存储实际值的堆,而基元类型将值存储在堆栈本身中。在这里,参考变量的值是它在存储实际值的堆所指的内存位置的地址。此引用通过“传递值”方法传递,而不是堆中的实际值。 –

0

尝试这样说,这与裁判

private static void Foo(ref Exception e) 
{ 
    e = new Exception("msg1"); 
} 

static void Main(string[] args) 
{ 
    try 
    { 
    int zero = 0; 
    int ecks = 1/zero; 
    } 
    catch (Exception e) 
    { 
    // I thought Exception is passed by reference, therefore Foo changes e to 
    // point to new Exception instance with message "msg1". 
    // But it stays the same 
    Foo(ref e); 
    throw e; 
    } 
} 
0

下面这行只是在当前的Foo方法栈中创建了一个新的对象。原始的主要方法仍然指向原始的异常对象。

e = new Exception("msg1"); 

要重现此为MyClass的类这样做,那么同样的情形会为MyClass的发生:

private static void Foo(MyClass m) { m = New MyClass(); m.Name = "bar"; }