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

Ada*_*ear 26 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; }
}
Run Code Online (Sandbox Code Playgroud)

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

Ada*_*son 38

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

  • @sibidiba:虽然最后的评论对我来说并不清楚,但你完全不正确.在该点*类可见的每个变量都有一个定义的值*.它没有任何随机性.对不起,您有权持有"未定义"的意见,就像您有权持有天空是紫色的意见一样,但两者同样不正确. (10认同)
  • @sibidiba,对象未处于"未定义"状态.对象可能无法从开发人员POV完全初始化,但如果他们想要,他们可以更改它.从语言POV,对象是完全构造的并且处于完全可接受和定义的状态. (8认同)
  • 我相信sibidiba的担心是,在构造函数完成之前,其他一些对象可以访问您的对象.如果不是做'MyProperty = new Class2(this)`你做了`MyId = MyRegistry.Register(this)`怎么办?或者如果Class2有一个注册表怎么办?关注sibidiba是有效的(虽然可以管理).将`this`作为参数传递没有任何内在错误,但必须保护构造函数中的这样做,以防止过早的引用泄漏. (4认同)
  • 不,"Class1"保证在这一点上完全构建.尽管已经调用了任何实例初始值设定项,但"Class2"尚未出现.当然,在此步骤之后在"Class2"构造函数中完成的任何其他操作尚未发生. (3认同)
  • 为什么在C#中没有问题而在其他语言中没有?如果Class2(Class1)决定使用传递的参数怎么办?此时Class1是半结构的,即处于未定义状态. (2认同)
  • 我必须坚持,如果构造函数没有完全运行,则对象处于未定义状态. (2认同)

pm1*_*100 21

不,这不是问题.这就是为什么'this'关键字存在,让你自己传递

  • 为了"允许你绕过自己"+1 (27认同)
  • 虽然我同意答案,但我不同意其原因.编程语言确实(并且应该)允许表达**通常是坏主意(例如goto,公共字段和全局变量).虽然规则偶尔需要打破,而语言应该允许这样做,但语言的可用功能对于什么是一般的良好实践来说是一个很差的指导. (5认同)

Joe*_*Joe 8

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

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


Dan*_*ant 8

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


Dan*_*Tao 7

只是为了缓解你的想法:

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

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