0

私はこの形式のコードにかなり定期的に出くわしました。(そして私は気まぐれだと思います)私は知っています、classBはref/outとしてラベル付けすることができます。私は、グッド/ベストプラクティスに従っているかどうかという観点から質問していますか、それともref/outのポイントを誤解していますか。

私が尋ねている理由は、オブジェクトのプロパティが更新されるかどうかわからないことが時々混乱するためです:/(意味idは、何が起こっているかを確認するためにメソッドにドリルダウンする必要があります)

    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

ClassAあなたの例では、とClassBが参照型であると仮定すると、classAclassBは値によって渡される参照です。メソッドの本体内でそれらに新しい値を割り当てた場合、これはメソッドスコープ外では効果がありません。例えば;

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;
}

ただし、例で行っているように、それらのプロパティを変更できます。

refandoutキーワードは、パラメーターが参照によって渡されていることを示すために使用されます。したがって、メソッドは参照パラメーターに新しい値を割り当てることができます。違いはref、メソッドに渡される前にパラメーターを割り当てる必要があるのに対しout、メソッドを終了する前にパラメーターを割り当てる必要があることです。

于 2012-11-19T15:27:39.617 に答える
2

あなたClassAは実際にクラスですか?

その場合、いいえ、ref/は必要ありませんout。さらに、誤解を招く可能性があります。

とにかく、クラスインスタンスは参照によって渡されます。ref参照自体outが変更される可能性があることを意味し(そしてそれ変更されることを意味します)、変更はメソッドの外部に表示されます。これはコードには当てはまりません。この例では、この参照によって参照されるオブジェクトのみが変更されます。

C#には、メソッドがオブジェクトのフィールドを変更できるかどうか、その変更メソッドを呼び出すかどうか、またはその他の方法で変更できるかどうかを制御する特別な修飾子はありません。メソッドは、公開されているすべてのものにアクセスできます。(または、同じクラス内の場合は、保護されているか、プライベートです。)そして、変更は外部で見られます。これは、両方のコードが同じオブジェクトを参照しているためです。

値型(構造体)では動作が異なることに注意してください。構造体を使用すると、呼び出されたメソッドはその値型への参照ではなく、そのコピーを取得します。したがって、構造体のフィールドへの変更(それ自体が悪い可変構造体がある場合)は、なしでは外部に表示されませんref

于 2012-11-19T15:25:05.313 に答える
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 に答える
1

Cal279が述べたように、実際にはclassAのポインタの値を変更するのではなく、参照型のプロパティを変更するため、ref修飾子は必要ありません。

C#には、特定のメソッドがパラメーターの状態に変更を加えることを示す明示的な構文はありませんが、メソッドに適切な名前を付けることで自分で変更できます。代わりにDoSomething、メソッドが呼び出されていることを確認してUpdateClassBください。それが何をするかを明確に説明する何か。FillClassBFromClassASynchronizeEntities

于 2012-11-19T15:26:43.197 に答える
1

オブジェクト(参照型)に変更を加えるため、厳密に言えばref/outは必要ありません。メソッドの記述の明確さは別の問題であり、適切なデザインパターンなどによって解決できると思います。

于 2012-11-19T15:24:05.500 に答える