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

时间:2011-07-17 13:32:50

标签: c# constructor

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

我正在对我的代码进行自我审核,以帮助“强化”它以便重复使用,我刚刚来到这里:

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意味着没有理由需要同时调用这两种语言,或者只是暗示语言只支持调用一种语言?

5 个答案:

答案 0 :(得分:22)

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

答案 1 :(得分:9)

这似乎是你想要的:

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

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

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

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

你正在正确阅读规范:它必须是一个或另一个。

答案 2 :(得分:8)

你没有,你不能。您可以通过:this(...)将构造函数调用转发给同一个类的另一个构造函数。该链中的最后一个构造函数必须由:base(...)

隐式或显式初始化基数

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

答案 3 :(得分:4)

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

    var SelectCellEditor = function(args) {
    var $select;
    var defaultValue;
    var scope = this;

    this.init = function() {

        if(args.column.options){
          opt_values = args.column.options.split(',');
        } else {
          opt_values ="".split(',');
        }
        option_str = "";
        for( i in opt_values ){
          v = opt_values[i];
          option_str += "<OPTION value='"+v+"'>"+v+"</OPTION>";
        }
        $select = $("<INPUT type='text' list='myoptions' tabIndex='0' class='editor-select' /><datalist id='myoptions'>"+ option_str +"</datalist>");
        $select.appendTo(args.container);
        $select.focus();
    };

    this.destroy = function() {
        $select.remove();
    };

    this.focus = function() {
        $select.focus();
    };

    this.loadValue = function(item) {
        defaultValue = item[args.column.field];
        $select.val(defaultValue);
    };

    this.serializeValue = function() {
        if(args.column.options){
          return $select.val();
        }else{
          return ($select.val() == "");
        }
    };

    this.applyValue = function(item,state) {
        item[args.column.field] = state;
    };

    this.isValueChanged = function() {
        return ($select.val() != defaultValue);
    };

    this.validate = function() {
        return {
            valid: true,
            msg: null
        };
    };

    this.init();
}

跨层次结构支持此功能,可能涉及任何数量或参数。

答案 4 :(得分:2)

这就是你要找的东西吗?

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());