标签: constructor-chaining

Delphi:如何为后代添加不同的构造函数?

更新:我最初的例子有点复杂.这是一个简单的8行示例,它解释了一个代码块中的所有内容.以下不编译会发出警告:

TComputer = class(TObject)
public
    constructor Create(Cup: Integer); virtual;
end;

TCellPhone = class(TComputer)
public
    constructor Create(Cup: Integer; Teapot: string); virtual;
end;
Run Code Online (Sandbox Code Playgroud)

注意:这个问题是我正在进行的关于Delphi中构造函数的子句的系列问题的第3部分

原始问题

如何将构造函数添加到现有类?

让我们给出一个假设的例子(即我在SO编辑器中输入的一个例子,它可能编译也可能不编译):

TXHTMLStream = class(TXMLStream)
public
   ...
end;
Run Code Online (Sandbox Code Playgroud)

进一步假设正常使用TXHTMLStream涉及在可以使用之前执行大量重复代码:

var
   xs: TXHTMLStream;
begin
   xs := TXHTMLStream.Create(filename);
   xs.Encoding := UTF32;
   xs.XmlVersion := 1.1;
   xs.DocType := 'strict';
   xs.PreserveWhitespace := 'true';
   ...

   xs.Save(xhtmlDocument);
Run Code Online (Sandbox Code Playgroud)

假设我想创建一个简化所有样板设置代码的构造函数:

TXHTMLStream = class(TXMLStream)
public
    constructor Create(filename: string; Encoding: TEncoding); virtual;
end;

constructor TXHTMLStream.Create(filename: string; Encoding: TEncoding);
begin
   inherited Create(filename);
   xs.Encoding …
Run Code Online (Sandbox Code Playgroud)

delphi constructor delphi-5 constructor-chaining

8
推荐指数
1
解决办法
2435
查看次数

是否保证在调用链式构造函数之前评估代码合约?

在我开始使用代码约定之前,有时在使用构造函数链时会遇到与参数验证相关的繁琐.

这是一个(人为的)示例最简单的解释:

class Test
{
    public Test(int i)
    {
        if (i == 0)
            throw new ArgumentOutOfRangeException("i", i, "i can't be 0");
    }

    public Test(string s): this(int.Parse(s))
    {
        if (s == null)
            throw new ArgumentNullException("s");
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望Test(string)构造函数链接Test(int)构造函数,并使用int.Parse().

当然,int.Parse()不喜欢有一个null参数,所以如果s为null,它将在我到达验证行之前抛出:

if (s == null)
    throw new ArgumentNullException("s");
Run Code Online (Sandbox Code Playgroud)

这使得检查毫无用处.

如何解决?好吧,我有时习惯这样做:

class Test
{
    public Test(int i)
    {
        if (i == 0)
            throw new ArgumentOutOfRangeException("i", i, "i can't be 0");
    }

    public Test(string s): …
Run Code Online (Sandbox Code Playgroud)

c# code-contracts constructor-chaining

8
推荐指数
1
解决办法
327
查看次数

这是使用构造函数链接的好方法还是坏方法?(......允许测试)

我在这里链接我的类构造函数的动机是,我有一个默认构造函数供我的应用程序主流使用,第二个允许我注入一个mock和一个stub.

在":this(...)"调用中看起来有点丑陋的"新"事物并且反直觉地从默认构造函数中调用参数化构造函数,我想知道其他人会在这做什么?

(仅供参考 - > SystemWrapper)

using SystemWrapper;

public class MyDirectoryWorker{

    //  SystemWrapper interface allows for stub of sealed .Net class.
    private IDirectoryInfoWrap dirInf;

    private FileSystemWatcher watcher;

    public MyDirectoryWorker()
        : this(
        new DirectoryInfoWrap(new DirectoryInfo(MyDirPath)),
        new FileSystemWatcher()) { }


    public MyDirectoryWorker(IDirectoryInfoWrap dirInf, FileSystemWatcher watcher)
    {
        this.dirInf = dirInf;
        if(!dirInf.Exists){
            dirInf.Create();
        }

        this.watcher = watcher;

        watcher.Path = dirInf.FullName;

        watcher.NotifyFilter = NotifyFilters.FileName;
        watcher.Created += new FileSystemEventHandler(watcher_Created);
        watcher.Deleted += new FileSystemEventHandler(watcher_Deleted);
        watcher.Renamed += new RenamedEventHandler(watcher_Renamed);
        watcher.EnableRaisingEvents = true;
    }

    public static string MyDirPath{get{return …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing constructor-chaining

6
推荐指数
1
解决办法
403
查看次数

德尔福:什么时候重新引入隐藏祖先,什么时候显示它们?

今天最近在Stackoverflow上我了解到:

我一直试图弄清楚这一切,所以这是另一个非常具体的问题,支持我处理构造函数的主要问题.


更新:替换了整个问题:

TComputer = class(TObject)
public
   constructor Create(Teapot: string='');
end;

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
Run Code Online (Sandbox Code Playgroud)

构建TCellPhone时,可以使用3个构造函数:

  • 杯子:整数
  • 杯子:整数; 茶壶:串
  • [茶壶:String ='']

问题:为什么constructor(Teapot: string='')不被隐藏?


现在我添加了第三个后代:

TComputer = class(TObject)
public
   constructor Create(Teapot: string='');
end;

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

TiPhone = class(TCellPhone)
public
   constructor Create(Cup: …
Run Code Online (Sandbox Code Playgroud)

delphi constructor delphi-5 constructor-chaining

6
推荐指数
1
解决办法
3412
查看次数

了解构造函数可见性

这是两个简单的类,最初都没有关键字(虚拟,重载,覆盖,重新引入):

TComputer = class(TObject)
public
   constructor Create(Teapot: Integer);
end;

TCellPhone = class(TComputer)
public
   constructor Create(Teapot: Integer; Handle: string);
end;
Run Code Online (Sandbox Code Playgroud)

我会将这些以上的定义表示为略短的:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
Run Code Online (Sandbox Code Playgroud)

构造时TCellPhone只有一个构造函数(int,string) - 因为祖先构造函数已被隐藏.我将指出可见的构造函数TCellPhone:

  • 茶壶:整数; 句柄:字符串

现在对于这个问题,前3个案例是有意义的,第4个案例没有:

1.祖先构造函数由后代隐藏:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
Run Code Online (Sandbox Code Playgroud)
  • Teapot: Integer; Handle: string

这是有道理的,祖先构造函数是隐藏的,因为我已经声明了一个新的构造函数.

2.祖先虚拟构造函数由后代隐藏:

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor …
Run Code Online (Sandbox Code Playgroud)

delphi constructor delphi-5 constructor-chaining

6
推荐指数
1
解决办法
363
查看次数

构造函数与基础构造函数调用一起链接

说我有以下内容:

class Base {
    public Base (int n) { }
    public Base (Object1 n, Object2 m) { }
}

class Derived : Base {

    string S;

    public Derived (string s, int n) : base(n) {
        S = s;
    }

    public Derived (string s, Object1 n, Object2 m) : base(n, m) {
        S = s; // repeated
    }
}
Run Code Online (Sandbox Code Playgroud)

注意我在Derived的两个重载中都需要形式参数n,因此我必须重复这一N = n;行.

现在我知道这可以封装到一个单独的方法中,但是你仍然需要来自两个重载的相同的两个方法调用.那么,是否有一种更"优雅"的方式来做到这一点,也许是通过this结合使用base

这样我可以有一个私有构造函数接受一个参数s,另外两个重载可以调用那个......或者这可能与拥有一个单独的私有方法相同?

c# inheritance constructor-chaining

6
推荐指数
1
解决办法
1538
查看次数

C#构造函数链接 - 更改执行顺序

我想知道在C#中链接构造函数时如何更改执行顺序.我见过的唯一方法需要在当前构造函数之外首先调用链式构造函数.

具体来说,请参考以下示例:

public class Foo {
  private static Dictionary<string, Thing> ThingCache = new Dictionary<string, Thing>();
  private Thing myThing;

  public Foo(string name) {
    doSomeStuff();
    if (ThingCache.ContainsKey(name)) {
      myThing = ThingCache[name];
    } else {
      myThing = ExternalStaticFactory.GetThing(name);
      ThingCache.Add(name, myThing);
    }
    doSomeOtherStuff();
  }

  public Foo(Thing tmpThing) {
    doSomeStuff();
    myThing = tmpThing;
    doSomeOtherStuff();
  }
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望通过这样做来减少代码重复(请注意,我承认在这个人为的示例中,没有保存太多代码,但我正在使用可以获得更多好处的代码.为了清楚起见,我使用此示例):

public class Foo {
  private static Dictionary<string, Thing> ThingCache = new Dictionary<string, Thing>();
  private Thing myThing;

  public Foo(string name) {
    if (ThingCache.ContainsKey(name)) {
      this(ThingCache[name]);
    } else {
      this(ExternalStaticFactory.GetThing(name)); …
Run Code Online (Sandbox Code Playgroud)

c# constructor constructor-chaining

6
推荐指数
2
解决办法
6759
查看次数

在C#4中,如何在具有重载构造函数的父类的子类中具有带可选参数的构造函数?

我有一个父类,它有一个重载的构造函数,我有一个子类,它有一个带有可选参数的构造函数.有没有办法让子类的构造函数仍然暴露父类的重载,同时保留它自己的可选参数?

这是两个类及其所需构造函数的一些示例代码:

class Foo {
    Foo(String arg0) 
    {
      // do some stuff with arg0
    }

    Foo(String arg0, List<x> arg1)
        : this(arg0)
    {
      // do some other stuff with arg1 that is special because we have an arg1
    }
}

class Bar : Foo {
    Bar(String arg0, List<y> arg2 = null, String arg3 = "") 
        : base(arg0)
    {
      // some third thing with arg2 and arg3
    }
}
Run Code Online (Sandbox Code Playgroud)

这是其他子类构造函数的方法签名我也想要公开父构造函数的重载,但问题是如何做到这一点:

Bar(String arg0, List<x> arg1, List<y> arg2 = null, String arg3 = "") …
Run Code Online (Sandbox Code Playgroud)

c# inheritance constructor subclass constructor-chaining

5
推荐指数
1
解决办法
7539
查看次数

检查构造函数是否调用另一个构造函数

在反射过程中,是否可以在C#中检查一个构造函数是否调用另一个?

class Test
{
    public Test() : this( false ) { }
    public Test( bool inner ) { }    
}
Run Code Online (Sandbox Code Playgroud)

我想确定每个ConstructorInfo是否在调用链的末尾.

c# reflection constructor cil constructor-chaining

5
推荐指数
1
解决办法
508
查看次数

关于Java中构造函数链接的困惑

据我所知,Constructctor Chaining就是这样

每当我们创建子类的对象(或调用子类构造函数)时,只有在
我们的子构造函数没有使用(对于相同的类)或超级关键字调用另一个构造函数时,才会首先自动调用父类的默认构造函数..来源:http://www.java67.com/2012/12/how-constructor-chaining-works-in-java.html

如果我的理解是正确的

然后为以下代码: -

Class First{
    First(){
    System.out.print("Hello");
    }

Class Second extends First{

    Second(int i)
    {
    System.out.println("Blogger");
    }
    Second(){
    this(2);    //default constructor is calling another constructor using this keyword
    }


public static void main(String[] args)
{
    Second ob = new Second();
}
Run Code Online (Sandbox Code Playgroud)

输出应该Blogger只是.

但输出是 HelloBlogger

所以看起来父类的默认构造函数仍然被调用.但引用该来源: -

2)如果你没有从父类或同一个类调用另一个构造函数,而不是Java调用default或没有超类的参数构造函数.

阅读更多:http://www.java67.com/2012/12/how-constructor-chaining-works-in-java.html#ixzz4qztuMrKW

所以请帮忙!

java constructor constructor-chaining

4
推荐指数
2
解决办法
312
查看次数