C# 通过考试是一种不好的做法吗;这";作为论据?

C# 通过考试是一种不好的做法吗;这";作为论据?,c#,C#,我现在很想写以下内容: public class Class1() { public Class1() { MyProperty = new Class2(this); } public Class2 MyProperty { get; private set; } } public class Class2() { public Class2(Class1 class1) { ParentClass1

我现在很想写以下内容:

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”作为参数传递是设计问题的标志吗?什么是更好的方法?

不,传递
这个
没有基本的设计问题。显然,这可能会被误用(例如,当调用实例本身的值时,相关类依赖于实例中存储的值,从而导致耦合太紧),但这并没有一般问题。

不,这不是问题。这就是为什么“this”关键字存在的原因,它允许您在设计中明确需要关系的情况下传递自己的信息。此模式通常在各种应用程序中用于表示“父”或“所有者”


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

很难从您发布的内容中说出。你应该问自己的问题是:为什么class2需要了解class1?class2在其生命周期中将对class1执行哪些类型的操作,有没有更好的方法来实现这种关系


这样做有充分的理由,但这取决于实际的类。

要给出一个示例,请查看访问者模式:

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

interface IAcceptVisitor {
  void Accept(IVisitor v);
}

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

我(根本)不知道C语言中的内存模型。但在许多语言(包括Java)中,将其从构造函数传递到另一个对象本质上是不安全的

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


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

通常我更喜欢将接口交给“child”类,因为这样可以减少耦合。如果Case2真的需要访问Cyr1的所有服务,Case2以这种方式公开(未完全封装并由Cyr1构造),那么我会考虑在构造函数中要求一个具体的Case1实例来表示一个可能的设计问题。

< P>只是要稍微放松一下:

将该
作为参数传递甚至是由BCL中的类完成的。例如,
List.Enumerator
类型保存对其父
List
对象的引用,以了解列表是否在枚举之间被修改(以及何时抛出
InvalidOperationException


当您有两个(或更多)类型实际上属于一个紧密结合、逻辑相关的组(如前面提到的集合和枚举器)时,这是非常标准的。我见过很多开发人员为了避免这种完全合理的耦合而不顾一切的情况。

虽然我同意这个答案,但我不同意这个原因。编程语言确实(而且应该)允许表达通常不好的想法(如goto、公共字段和全局变量)。虽然有时需要打破规则,语言也应该允许这样做,但语言的可用功能对于一般良好实践的指导作用很差。虽然我喜欢答案的幽默性,但它怎么能比大多数其他答案更高?这里没有任何有效的理由。无条件语句实际上是不正确的,因为您必须控制对象的哪些部分已经正确设置,哪些没有正确设置(基本上是传递给
这个
的调用序列,以及构造函数发生的其余工作)因为它简洁地回答了一个简洁的问题:“使用它是不是设计拙劣的标志?”;一般来说,这不是(相对于goto,过于公开的东西;太多的朋友,…)为什么在C#而不是在其他语言中是可以的?如果Class2(Class1)决定使用传递的参数,该怎么办?Class1此时是半构造的,即处于未定义状态。不,
Class1
保证此时是完全构造的<虽然调用了任何实例初始值设定项,但尚未调用代码>类2
。当然,在此步骤之后在
Class2
构造函数中执行的任何其他操作都尚未发生。@sibidiba,对象未处于“未定义”状态。对象可能没有从开发人员的POV中完全初始化,但是如果他们愿意,他们可以更改它。从语言的角度来看,对象是完全构造的,并且处于完全可接受和定义的状态。@sibidiba:虽然我不清楚最后的评论,但你完全不正确。在该点对类可见的每个变量都有一个定义的值。这不是随机的。很抱歉,你有权持有“未定义”的观点,就像你有权持有天空是紫色的观点一样,但两者都是不正确的。我相信西比迪巴担心的是,在你的构造函数完成之前,其他对象会访问你的对象。如果您没有执行
MyProperty=newclass2(此)
,而是执行
MyId=MyRegistry.Register(此)
,该怎么办?或者如果Class2有一个注册表呢。关于sibidiba的担忧是有效的(尽管可以管理)。将
这个
作为参数传递本身并没有什么错误,但是在构造函数中这样做必须得到保护,以防止过早的引用泄漏。当涉及到C#时,您肯定是不正确的,我认为Java也是不正确的(尽管我目前找不到引用)。与C和C++不同,java和C语言都有明确的规范,说明如何在新构造的对象中创建字段。虽然成员字段的值可能尚未初始化,但它们肯定不是未定义的(在C和C++的单词意义上)。@丹尼尔:一个单位化的对象处于未定义状态。它永远不应该哈