0

I've come across code in this format quite regularly.. (And I guess I'm nitpicking) I know, classB can be labeled as ref/out. I'm asking from a viewpoint of if going by good/best practices, or am I misunderstanding the point of ref/out.

The reason I'm asking is, that I'm finding it confusing at times not knowing if properties in my object is going to be updated or not :/ (Meaning id need to drill down into the method to see whats going on)

    public ClassB GetSomething()
    {
       var classB = new ClassB();

       ClassA classA = .... // some code to get new obj

       //from a glance i'm not ale to tell that classB gets updated/assigned to  
       this.DoSomething(classA , classB);

       return classB;
    }

    private void DoSomething(ClassA classA, ClassB classB)
    {
          classB.Property = classA.something.Property;
    }
4

5 回答 5

3

在您的示例中,假设ClassAandClassB是引用类型,那么classAandclassB是按值传递的引用。如果您在方法的主体内为它们分配一个新值,那么这将不会在方法范围之外产生任何影响。例如;

private void Caller()
{
    var classA = new ClassA();
    var classB = new ClassB();

    DoSomething(classA, classB);

    // classA and classB still point to the instances from before the call to DoSomething()
}

private void DoSomething(ClassA classA, ClassB classB)
{
      classA = null;
      classB = null;
}

但是,您可以改变它们的属性,就像您在示例中所做的那样。

和关键字用于指示参数是通过引用传递的,因此该方法ref可以引用参数分配新值。区别在于参数必须在传递给方法之前分配,而参数必须在方法退出之前分配。outrefout

于 2012-11-19T15:27:39.617 回答
2

该代码很好 - classB 已经是参考。如果您使用了 ref,那么您将获得对引用的引用,这不是这里的意图。但它也有它的用途;考虑一下:

private void Foo()
{
    object myObject = new object();
    DoSomething(ref myObject);
}
private void DoSomething(ref object myObject)
{
  myObject = new object();
}

调用 DoSomething 时,它会将 Foo 中的 myObject 变量分配给的对象更改为指向在 DoSomething 中创建的对象。

于 2012-11-19T15:28:41.470 回答
2

ClassA真的是一个班级吗?

在这种情况下,不,您不需要ref/ out,而且这会产生误导。

无论如何,类实例都是通过引用传递的。ref意味着引用本身可能会被更改(并且out意味着它将被更改)并且更改将在方法之外可见,这不是您的代码的情况:在您的示例中,只有此引用引用的对象被更改。

在 C# 中,没有特殊的修饰符来控制方法是否可以更改对象的字段、调用其变异方法或以其他方式更改它。这些方法可以访问公开可用的所有内容。(或者受保护的,或者私有的,如果在同一个类中。)并且可以在外部看到更改,因为,两个代码都在查看同一个对象。

请注意,它对于值类型(结构)的工作方式不同:对于结构,被调用的方法不是对该值类型的引用,而是它的副本。因此,如果没有ref.

于 2012-11-19T15:25:05.313 回答
1

严格来说,当您更改对象(引用类型)时,不需要 ref/out。我认为编写方法的清晰度是一个单独的问题,可以通过合适的设计模式等来解决。

于 2012-11-19T15:24:05.500 回答
1

正如 Cal279 所提到的,您不需要 ref 修饰符,因为您实际上并没有更改 classA 指针的值,而是更改了引用类型的属性。

C# 没有明确的语法来标记给定方法对参数状态的更改,但您可以通过适当地命名该方法来自己这样做:DoSomething确保调用该方法而不是UpdateClassBFillClassBFromClassA,甚至是SynchronizeEntities。明确描述它的作用的东西。

于 2012-11-19T15:26:43.197 回答