将“this”作为论据传递是不好的做法?

时间:2010-03-16 16:33:37

标签: c#

我现在想写下以下内容:

public class Class1() 
{
    public Class1() 
    {
        MyProperty = new Class2(this);
    }

    public Class2 MyProperty { get; private set; }
}

public class Class2() 
{
    public Class2(Class1 class1) 
    {
        ParentClass1 = class1;
    }

    public Class1 ParentClass1 { get; set; }
}

将“this”作为参数传递给设计问题的标志?什么是更好的方法?

8 个答案:

答案 0 :(得分:37)

不,传递this没有基本的设计问题。显然,这可能会被误用(例如,当一个相关的类依赖于你自己的值所需的相关类依赖于存储在你的实例中的值时,会产生过于紧张的耦合),但它没有普遍的问题。

答案 1 :(得分:20)

不,这不是问题。这就是为什么'this'关键字存在,让你自己通过

答案 2 :(得分:8)

很难说你发布了什么。你应该问自己的问题是:为什么class2需要知道class1? class2在其生命周期中将在class1上执行哪些类型的操作,是否有更好的方法来实现该关系?

这样做有正当理由,但这取决于实际的类别。

答案 3 :(得分:8)

通常我更喜欢将接口传递给'child'类,因为这会减少耦合。如果Class2确实需要访问Class1的所有服务,并且Class2以这种方式公开(没有完全封装并由Class1构造),那么我会考虑在构造函数中要求一个具体的Class1实例,以表明可能的设计问题。

答案 4 :(得分:6)

只是为了缓解你的想法:

this作为参数传递甚至由BCL中的类完成。例如,List<T>.Enumerator类型保存对其父List<T>对象的引用,以便知道列表是否在枚举之间被修改(因此何时抛出InvalidOperationException)。

当你有两个(或更多)类型实际上属于一个紧密结合的逻辑相关组(例如前面提到的集合和枚举器)时,这是非常标准的。我已经看到很多情况下,开发人员向后弯腰以避免这种完全合理的耦合,没有实际原因。

答案 5 :(得分:3)

举个例子,看一下访客模式:

interface IVisitor {
 Visit(SomeClass c);
 Visit(AnotherClass c);
}

interface IAcceptVisitor {
  void Accept(IVisitor v);
}

public SomeClass : IAcceptVisitor {
  void Accept(IVisitor v) {
    v.Visit(this);
  }
}

答案 6 :(得分:3)

我不太清楚C#中的内存模型(根本没有)。但是将 this 从构造函数传递给另一个对象在许多语言(包括Java)中本质上都是不安全的。

如果您在构造函数中,则尚未构造该对象。如果此时另一个对象决定使用传递的 this 参数,它将引用处于未定义状态的对象。

在您的示例中,这种未定义的用法不会发生,但您如何保证将来不会这样?如果有人以一种在自己的构造函数中使用ParentClass1中的东西的方式对Class2进行子类化/修改会怎么样?

答案 7 :(得分:2)

不,不是问题,如果,您的设计中明确需要关系。此模式经常在各种应用程序中用于表示“父”或“所有者”。

我在编译器实现或GUI工具包中遍历树时特别使用它。