2009-11-25 36 views

回答

6

要继续约翰的回答,而是执行此操作:

string username; 
if (myDic.TryGetValue("username", out username)) 
{ 
    user.Username = username; 
} 
3

你可以在VB中做到这一点,但不是C#。

VB将生成一个临时变量(在堆栈上),将其地址传递给out值,然后在方法调用后对该属性进行赋值。

一般来说VB是这样做的,因为它在整个地方都有很多隐含的东西。这只是它的工作方式。另一方面,C#往往避开隐含性作为其哲学的一部分。这就是为什么,例如,你必须向呼叫站点添加“out”,以便让参数起作用,并且为什么它不支持扩展方法的第一个参数的“ref”参数。

在呼叫站点使用显式的“out”语法可以在这里支持属性。但是,我相信他们不这样做的原因是因为VB使用的技巧对于属性的行为与对字段的行为不完全相同。使用字段时,分配会立即发生在方法内发生的地方。如果方法中有其他代码(通过调用对象的方法)读取该字段,它将读取通过输出参数分配的新字段值。

使用VB技巧的属性,该属性直到方法返回后才会被赋值。这意味着在out参数分配后直接读取属性的任何代码都会读取旧值。

这里是什么,我的意思是一个简单的例子:)

class C 
{ 
    private int m_bar; 

    public int Bar { get { return m_bar; } set { m_bar = value; }} 

    void foo(out int x) 
    { 
     x = 2; 
     Console.WriteLine(Bar); 
    } 

    void DoStuff() 
    { 
     foo(out m_bar); //outputs 2 
     Bar = 0; 
     //pretend this works 
     foo(out Bar); //outputs 0 
     Console.WriteLine(Bar); // outputs 2 
    } 
} 

内DoStuff(,你会得到不同的行为,为第一次调用foo的比你从第二个呼叫为foo会,虽然大多数人会期望他们以同样的方式行事。

通常C#试图避免这些类型的事情。

这是我的猜测,为什么他们不支持它(规范只是说不支持,它并不真正说为什么)。

相关问题