Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 引导初始化_.net_Vb.net - Fatal编程技术网

.net 引导初始化

.net 引导初始化,.net,vb.net,.net,Vb.net,我有两个类,一个继承自另一个。基类是MustInherit/abstract,并定义MustOverride/abstract属性 作为基类初始化的一部分,它根据抽象属性的值设置一个变量。问题是继承类接受应该分配给重写属性的值作为其参数。继承的类设置此属性,但不是在调用基类的初始值设定项之前 基本上,我需要初始化基类的一部分,然后允许继承类初始化它的一些属性,然后返回基类以完成初始化更多属性 我会使属性成为基类的一部分,但是继承类使用强类型,而基类只需要一个接口 代码示例: MustInheri

我有两个类,一个继承自另一个。基类是MustInherit/abstract,并定义MustOverride/abstract属性

作为基类初始化的一部分,它根据抽象属性的值设置一个变量。问题是继承类接受应该分配给重写属性的值作为其参数。继承的类设置此属性,但不是在调用基类的初始值设定项之前

基本上,我需要初始化基类的一部分,然后允许继承类初始化它的一些属性,然后返回基类以完成初始化更多属性

我会使属性成为基类的一部分,但是继承类使用强类型,而基类只需要一个接口

代码示例:

MustInherit Class A
  MustOverride Property X As IExample

  Sub New()
    ' Do some stuff
    _privateY = X.Foo() ' NullReferenceException
  End Sub
End Class

Class B
  Inherits A

  Override Property X As IExample ' returns StrongX
  Property StrongX As ConcreteExample ' ConcreteExample implements IExample

  Sub New(x As ConcreteExample)
    MyBase.New(x)
    StrongX = x
  End Sub
End Class

您可以使用一个
惰性

公共抽象类A
{
private Lazy_privateY=new Lazy(()=>this.X.Foo());
}

您可以使用一个
懒惰的

公共抽象类A
{
private Lazy_privateY=new Lazy(()=>this.X.Foo());
}

正是由于这个原因,不应该在构造函数中调用抽象成员

如果您可以控制抽象类,我建议通过基类构造函数传入该值

public abstract class A
{
    public A(IExample x)
    {
        // Do Stuff
        var _privateY = x.Foo();
    }
}

public class B : A
{
    public B(IExample x):base(x)    {}
}

正是由于这个原因,不应该在构造函数中调用抽象成员

如果您可以控制抽象类,我建议通过基类构造函数传入该值

public abstract class A
{
    public A(IExample x)
    {
        // Do Stuff
        var _privateY = x.Foo();
    }
}

public class B : A
{
    public B(IExample x):base(x)    {}
}
编辑:对不起,我的答案是C#:(

一种选择是让基本抽象类调用子类可以实现的虚拟(或抽象)初始化方法:

public abstract class A
{
    public abstract IExample X { get; set; }

    private object _privateY;

    protected A()
    {
        PreInit();

        PostInit();
    }

    protected abstract void PreInit();

    protected virtual void PostInit()
    {
        if (X == null)
            throw new InvalidOperationException("Must assign a value to X.");

        _privateY = X.Foo();
    }
}
然后在
B
中,覆盖
PreInit
并分配数据:

public class B : A
{
    public override IExample X { get; set; }

    public B()
    {

    }

    protected override void PreInit()
    {
        X = new ConcreteExample();
    }
}
编辑:对不起,我的答案是C#:(

一种选择是让基本抽象类调用子类可以实现的虚拟(或抽象)初始化方法:

public abstract class A
{
    public abstract IExample X { get; set; }

    private object _privateY;

    protected A()
    {
        PreInit();

        PostInit();
    }

    protected abstract void PreInit();

    protected virtual void PostInit()
    {
        if (X == null)
            throw new InvalidOperationException("Must assign a value to X.");

        _privateY = X.Foo();
    }
}
然后在
B
中,覆盖
PreInit
并分配数据:

public class B : A
{
    public override IExample X { get; set; }

    public B()
    {

    }

    protected override void PreInit()
    {
        X = new ConcreteExample();
    }
}

(标记为C#和VB.NET,因为它与这两种语言都相关,但如果有建议,我希望有更多相关的标记。)仅仅因为C#和VB.NET都是面向对象的,并不意味着这个问题符合C#问题。这个问题与C#无关!!!尽管我在这个项目中使用了这两种语言,但我意识到这个问题在VB.NET或C#下都不完全合适。然而,OOP实现细节是针对.NET语言家族的。(标记为C#和VB.NET,因为它与这两种语言都相关,但如果有建议,我希望有更多相关的标记。)仅仅因为C#和VB.NET都是面向对象的,并不意味着这个问题符合C#问题。这个问题与C#无关!!!虽然我在这个项目中使用了这两种语言,但我意识到这个问题在VB.NET或C#下都不完全合适。然而,OOP实现细节是针对.NET语言家族的。Could甚至有
public B():base(new ConcreteExample())
,正如Eric Lippert所说,“从构造函数调用虚拟方法是一种糟糕的编程实践。从构造函数调用虚拟方法是一个坏主意,因为派生类上的方法可能在派生类构造函数运行之前运行。”Kevin的解决方案是优雅的,并且有正确的想法。感谢文档。构造函数参数方法对我来说是可行的,但我不是一个大粉丝,因为它会让参数的数量感觉过多,并且可能会给人一种错误的印象,即基类正在以某种方式设置属性(或者应该设置)但是,它看起来是唯一的选择。它一点也不坏@Cyborgx37,这是一种很好的依赖注入方法。类
a
实际上要求它有一个
IExample
的实现,因此将它作为构造函数每次都满足了这一需要,并使创建子类的任何开发人员都能立即识别它(虽然您可能想考虑一个空校验,也许是一个代码>调试。断言< /代码>)。基类设置属性也是可以的。也许你可以将属性设置为public get;private set;
并放弃
抽象
?谢谢@Chris。有时你会被某个特定的实现所包围,以至于需要其他人指出显而易见的东西。我想我会放弃抽象-这是r根本没有令人信服的理由。甚至可以像Eric Lippert所说的那样有
public B():base(new ConcreteExample())
,“从构造函数调用虚拟方法是一种不好的编程实践。从构造函数调用虚拟方法是一种不好的做法,因为派生类上的方法可能在派生类构造函数运行之前运行。“Kevin的解决方案是优雅的,并且有正确的想法。感谢您提供的文档。构造函数参数方法对我来说很常见,但我不是一个很喜欢的方法,因为它会让参数的数量感觉过多,并且可能会给人一种错误的印象,即基类正在以某种方式设置属性(或者应该设置)但是,它看起来是唯一的选择。它一点也不坏@Cyborgx37,这是一种很好的依赖注入方法。类
a
实际上要求它有一个
IExample
的实现,因此将它作为构造函数每次都满足了这一需要,并使创建子类的任何开发人员都能立即识别它(虽然您可能想考虑一个空校验,也许是一个代码>调试。断言< /代码>)。基类设置属性也是可以的。也许你可以将属性设置为public get;private set;
并放弃
摘要
?谢谢@Chris。有时你会被某个特定的实现所包围,以至于需要其他人指出显而易见的地方。我想我会放弃摘要