English 中文(简体)
代码执行后呼叫建构基地
原标题:Call Constructor Base after Code Execution

让我们假设我们有A类和B类。 B类扩展A类。 (分类B:类A)

现在让我们说,每当我即时使用B类时, 我喜欢运行一些随机代码, 然后再叫"基地"到达A类的建造者。

类似 :

class ClassA
{
    public ClassA()
    {
        Console.WriteLine("Initialization");
    }  
}

class ClassB : ClassA
{
    public ClassB() //: base() 
    {
        // Using :base() as commented above, I would execute ClassA ctor before                                                         //          Console.WriteLine as it is below this line... 
        Console.WriteLine("Before new");
        //base() //Calls ClassA constructor using inheritance
        //Run some more Codes here...
    }
}

用我通常使用的编程语言,我可以这样做,只需在 Console.WriteLine 之后拨打 super () 。 但我无法在 C# 中做到这一点。 有没有其他语法或其他方法可以这样做?

最佳回答

使用实例变量初始化器,

using System;

class ClassA
{
    public ClassA()
    {
        Console.WriteLine("Initialization");
    }  
}

class ClassB : ClassA
{
    private readonly int ignoreMe = BeforeBaseConstructorCall();

    public ClassB()
    {
    }

    private static int BeforeBaseConstructorCall()
    {
        Console.WriteLine("Before new");
        return 0; // We really don t care
    }
}

class Test
{
    static void Main()
    {
        new ClassB();
    }    
}

less hacky 的操作方式是重新思考您如何构建要启动的 ClassB 。 用户不是直接调用构建器, 而是提供一个静态的调用方法 :

public static ClassB CreateInstance()
{
    Console.WriteLine("Before initialization stuff");
    return new ClassB();
}
问题回答

另一种黑客,如果你可以逃脱 调用静态方法。

public class ClassA
{
    public ClassA()
    {
        Debug.WriteLine("Call A Constructor");
    }
}

public class ClassB:ClassA
{
    public ClassB():this(aMethod())
    {
    }

    private ClassB(object empty):base()
    {
        Debug.WriteLine("Class B Second Constructor");
    }

    private static object aMethod()
    {
        Debug.WriteLine("Run me First");
        return null;
    }
}

实际上,你可以:

class Foo
{
    public Foo(string s)
    {
        Console.WriteLine("inside foo");
        Console.WriteLine("foo" + s);
    }
}

class Bar : Foo
{
    public Bar(string s) : base(((Func<string>)(delegate ()
    {
        Console.WriteLine("before foo");
        return "bar" + s;
    }))())
    {
        Console.WriteLine("inside bar");
    }
}

class Program
{
    static void Main(string[] args)
    {
        new Bar("baz");
    }
}

产出:

before foo
inside foo
foobarbaz
inside bar

但是,如果可能的话,我宁愿不使用这种伎俩。

另一种优雅的解决办法是彻底重新思考天体是如何构造的。在您基础类的构建器中,您可以调用您自己的 construct 函数,您可以省略依赖的未来构建器,具体方式如下:

public class ClassA
{
    public ClassA()
    {
        Construct();
    }

    public virtual void Construct()
    {
        Console.WriteLine("3");
    }
}

public class ClassB : ClassA
{
    public override void Construct()
    {
        Console.WriteLine("2");
        base.Construct();
    }
}

public class ClassC : ClassB
{
    public override void Construct()
    {
        Console.WriteLine("1");
        base.Construct();
    }
}

C#不允许在与爪哇不同的建筑体内呼叫基建人员。

C# 无法做到这一点。 您的最好赌注是将代码在父权内部输入到它自己的方法中, 然后在孩子准备好后从孩子那里调用它 。

我感到惊讶的是,没有人建议使用抽象方法 — — 尽管它确实依赖作为抽象阶级实施的基数,而这种基数不会适用于所有案例(尽管如果Yu必须这样做的话,你可以简单地将遗产叉开并堆叠在上方的非抽象物 ) 。 这样做的好处是确保您的代码的完整性,而不必诉诸黑客主义。 因为我们使用的是抽象的,所以不可能在没有宣布 InitCode 的情况下对衍生的类别进行即时处理。

using System;

abstract class ClassA
{
    internal abstract initCode();
    public ClassA()
    {
        initCode();
        Console.WriteLine("Initialization");
    }  
}

class ClassB : ClassA
{
    public ClassB()
    {
    }
    
    internal override initCode()
    {
        Console.WriteLine("Before new");
        return 0; // We really don t care
    }
}

//If you need to effectively get the non-abstract of ClassA
class ClassC : ClassA
{
    public ClassB()
    {
    }
    
    internal override initCode()
    {
    }
}

You can not call base constructor. But a different thing is that when you declare an object of derived class both constructor derived and base is called.

    class ClassA
{
    public ClassA()
    {
        Console.WriteLine("Initialization");
    }  
}

class ClassB : ClassA
{
    public ClassB() //: base() 
    {
        // Using :base() as commented above, I would execute ClassA ctor before                                                         //          Console.WriteLine as it is below this line... 
        Console.WriteLine("Before new");
        //base() //Calls ClassA constructor using inheritance
        //Run some more Codes here...
    }
}
void main(string[] args)
    {
      ClassB b = new ClassB();

    }

最近我遇到了一个场景, 我需要计算一些逻辑, 然后再将结果传递到基地。

我可以做一些类似

public SomeConstructor: base(FlagValue == FlagValues.One || FlagValues.Two ? "OptionA" : "OptionB")
{

}

但我发现这是丑陋的, 并且可以得到非常长的横向。所以我选择了使用Func匿名方法。

例如,想象你有一个基本等级,

public class SomeBaseClass
{
  public SomeBaseClass(Func<string> GetSqlQueryText){
    string sqlQueryText = GetSqlQueryText();
    //Initialize(sqlQueryText);
  }
}

现在你继承了它,想要做一些逻辑来决定 sql 查询文本,

public class SomeSqlObject : SomeBaseClass
{
  public SomeSqlObject(ArchiveTypeValues archiveType)
        : base(delegate()
        {
            switch (archiveType)
            {
                case ArchiveTypeValues.CurrentIssues:
                case ArchiveTypeValues.Archived:
                    return Queries.ProductQueries.ProductQueryActive;
                case ArchiveTypeValues.AllIssues:
                    return     string.Format(Queries.ProductQueries.ProductQueryActiveOther, (int)archiveType);
                default:
                    throw new InvalidOperationException("Unknown archiveType");
            };
        })
    {
        //Derived Constructor code here!
    }

}

这样您就可以在呼叫基地之前执行代码, (在我看来) 它不是真正的黑客。

我也有同样的问题。我发现这个解决方案是最好的,如果你没有进入基础班。

public class BaseClass
{
    public BaseClass(string someValue)
    {
        Console.WriteLine(someValue);
    }
}

public class MyClass : BaseClass
{
    private MyClass(string someValue)
        : base(someValue)
    {
    }

    public static MyClass GetNewInstance(string someValue, bool overrideValue = false)
    {
        if (overrideValue)
        {
            someValue = "42";
        }
        return new MyClass(someValue);
    }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签