Call Constructor Base after Code Execution

后端 未结 9 2003
攒了一身酷
攒了一身酷 2021-02-12 12:33

Let say we have Class A and Class B. ClassB extends Class A. (ClassB : ClassA)

Now let\'s say that whenever I instantiate ClassB, I\'d like to Run some Random code and o

相关标签:
9条回答
  • 2021-02-12 13:31

    Recently I ran into a scenario where I needed to calculate some logic before passing the result into base.

    I could just do something like

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

    But I find that to be ugly, and can get really long horizontally. So I opted instead to use Func Anonymous methods.

    E.g. imagine you have a base class,

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

    Now you inherit from that and want to do some logic to determine the sql query text,

    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!
        }
    
    }
    

    In this way you can execute code before Base is called and (in my opinion) it's not really hacky.

    0 讨论(0)
  • 2021-02-12 13:35

    Another elegant solution would be to completely rethink how your objects are constructed. In the constructor of your base class you can call your own construct function, and you omit dependent future constructors, in the following way:

    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();
        }
    }
    
    0 讨论(0)
  • 2021-02-12 13:38

    Actually, you can:

    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");
        }
    }
    

    Output:

    before foo
    inside foo
    foobarbaz
    inside bar
    

    But I will prefer to not use this trick if it is possible.

    0 讨论(0)
提交回复
热议问题