我如何调用构造函数初始值设定项、base() 和 this()?

发布于 2024-11-24 06:03:04 字数 895 浏览 1 评论 0原文

这很容易解决,但我只是好奇我是否可以使用某种语言功能,或者该语言不允许它意味着我在类设计中犯了逻辑错误。

我正在对我的代码进行自我审查,以帮助“强化”它以供重复使用,我刚刚遇到:

public partial class TrackTyped : Component
{
    IContainer components = null;

    public TrackTyped()
        : base()
    {
        InitializeComponent();
    }

    public TrackTyped(IContainer container)
        : base()
    {
        container.Add(this);
        InitializeComponent();
    }
}

当我在两个构造函数中看到同一行代码时,我通常会做的事情是让一个函数用“this”调用另一个函数()”,但我似乎做不到。

如果我正确地阅读了规范(我刚刚开始尝试阅读规范,所以我可能不正确):

10.11 Instance Constructors
   constructor-declarator:
      identifier   (   formal-parameter-listopt   )   constructor-initializeropt
   constructor-initializer:
      :   base   (   argument-listopt   )
      :   this   (   argument-listopt   )

这就是说我只能拥有其中之一。

问题:10.11 是否意味着没有理由需要同时调用两者,或者只是意味着该语言仅支持调用其中一个?

This is easy to work around, but I just curious if I could be using a language feature or possibly the fact that the language disallows it means I'm making a logical error in class design.

I'm doing a self review of my code to help "harden" it for re-use and I just came accross:

public partial class TrackTyped : Component
{
    IContainer components = null;

    public TrackTyped()
        : base()
    {
        InitializeComponent();
    }

    public TrackTyped(IContainer container)
        : base()
    {
        container.Add(this);
        InitializeComponent();
    }
}

What I usually do when I see the same line of code in two constructors is make one call the other with "this()" but I can't seem to do it.

If I read the spec right (I just started trying to read the spec so I may not be right):

10.11 Instance Constructors
   constructor-declarator:
      identifier   (   formal-parameter-listopt   )   constructor-initializeropt
   constructor-initializer:
      :   base   (   argument-listopt   )
      :   this   (   argument-listopt   )

It's saying I can only have one of those.

QUESTION: is 10.11 implying that there's no reason to need to call both or is it simply implying that the language only supports calling one?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

薯片软お妹 2024-12-01 06:03:04

无需同时调用两者,因为 this 重定向到另一个将调用 base 的构造函数。

There is no need to call both, because this redirects to another constructor that will call base.

做个ˇ局外人 2024-12-01 06:03:04

你不这样做,也不可能。您可以通过 :this(...) 将构造函数调用转发给同一个类的另一个构造函数。该链中的最后一个构造函数必须通过 :base(...) 隐式或显式初始化基类

。假设类 A 有两个构造函数。一种使用 :base(2) 初始化基址,另一种使用 :base(3) 初始化基址。如果允许第一个构造函数也指定 :this (/*call the other ctor*/) 基类应该如何初始化:使用 2 或 3?这就是为什么这些事情是不允许的

You don't and you can't. You can forward the constructor call to another constructor of the same class by :this(...). The last constructor in that chain will have to initialize the base either implicitly or explicitly by :base(...)

Suppose class A has two constructors. One initializes the base with :base(2), the other with :base(3). If the first constructor was allowed to also specify :this (/*call the other ctor*/) how should the base have been initialized: with 2 or 3? That's why these things aren't allowed

城歌 2024-12-01 06:03:04

这似乎就是您想要的:

public partial class TrackTyped : Component
{
    IContainer components = null;

    public TrackTyped()
        : base()
    {
        InitializeComponent();
    }

    public TrackTyped(IContainer container)
        : this()
    {
        container.Add(this);
    }
}

不过,第二个构造函数中的语句顺序现在不同了。如果这很重要,那么就没有真正的好方法来做你想做的事情,因为即使你有相同的行,功能也有细微的不同。在这种情况下,您只需重复单行即可。别出汗。

并且您正确地阅读了规范:它必须是其中之一。

This seems to be what you want:

public partial class TrackTyped : Component
{
    IContainer components = null;

    public TrackTyped()
        : base()
    {
        InitializeComponent();
    }

    public TrackTyped(IContainer container)
        : this()
    {
        container.Add(this);
    }
}

The order of the statements in the second constructor is different now, though. If that matters, then there's not really a good way to do what you want, since even though you have the same line, the functionality is subtly different. In that case, you'll just have to have the single line repeated. Don't sweat it.

And you are reading the spec correctly: it does have to be one or the other.

假面具 2024-12-01 06:03:04

通常在具有多个要通过构造函数初始化的属性的类中完成,其中一些属性是可选的。
我们有一个最大的构造函数,它接受调用基本构造函数的所有参数。所有其他构造函数通过将 null/默认值传递给这个大构造函数来重定向到此构造函数。这样,所有初始化代码都保留在一个位置,可供其他人重用。

public MissingEntityException(Type type, string criteria, string message = "") 
    : this(type, criteria, message, null)
{           
}

public MissingEntityException(Type type, string criteria, string message, Exception innerException) 
     : base(message, innerException) 
{
    this.EntityType = type;
    this.Criteria = criteria;
}

这是跨层次结构支持的,并且可以涉及任意数量或参数。

Usually done in a class having multiple properties to be initialized via constructor and some of them being optional.
We have a one biggest constructor which takes in ALL parameters which calls the base constructor. All other constructors redirect to this constructor by passing a null/default value to this big constructor. This way, all initialization code remains in a single place, reusable by others.

public MissingEntityException(Type type, string criteria, string message = "") 
    : this(type, criteria, message, null)
{           
}

public MissingEntityException(Type type, string criteria, string message, Exception innerException) 
     : base(message, innerException) 
{
    this.EntityType = type;
    this.Criteria = criteria;
}

This is supported across hierarchy and can involve any number or parameters.

执笏见 2024-12-01 06:03:04

这是您要找的吗?

public partial class TrackTyped : Component
{
    IContainer components = null; 
    public TrackTyped() : base()
    {
        // logic for InitializeComponent() here
    } 

    public TrackTyped(IContainer container) : this()
    {
        container.Add(this)
    }
}

顺便说一句:这是第二个 ctor 的一个有趣用法:

var a = TrackTyped(container);

我想知道删除第二个 ctor 并执行此操作对您来说是否会更清楚? (最终结果相同)

container.Add(new TrackTyped());

is this what you are looking for?

public partial class TrackTyped : Component
{
    IContainer components = null; 
    public TrackTyped() : base()
    {
        // logic for InitializeComponent() here
    } 

    public TrackTyped(IContainer container) : this()
    {
        container.Add(this)
    }
}

btw: that's an interesting usage for the second ctor:

var a = TrackTyped(container);

I wonder if deleting the second ctor and doing this is would be clearer for you? (same end result)

container.Add(new TrackTyped());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文