如何防止派生类的属性的多次初始化

本文关键字:初始化 属性 派生 何防止 | 更新日期: 2023-09-27 18:04:42

下面的代码是我真实项目的一个简短的"摘要",它只包含了理解我的问题的相关部分。(并且不想用原始代码毁了某人的一天)。

想象你有4个班级:事业部、分公司、部门和团队。每个类都按照这个顺序继承基类。

最终目标:返回一个division对象,该对象保存List of 7 Branches,每个Branch保存List of 7 Departments,每个Department保存List of 7 Teams。例如,我将能够从外部访问每个类实例:

division d = new division();
d.CreateDivisionStructure();
int Example = d.ListOfBranches[5].ListOfDepartments[4].ListOfTeam[3].SomeIntegerProperty;

(原始代码中有列表、重写函数、属性等)

问题:想象下面代码中的protected string _myVar是一个Datatable,需要通过myVar属性初始化,并且需要大量消耗资源的SQL查询。因此,我希望对所有"划分单元结构"的创建只初始化一次protected string _myVar。在下面的代码中,protected string _myVar将为空64次,并将初始化64次(我的理解是每个单元7次,每个base()调用一次)。

我怎样才能做到这一点?

我试了很多其他的方法,但都不能解决这个问题。我将感激任何帮助,不同的思路或建议。

  class Program
    {
        static void Main(string[] args)
        {
            division d = new division();
            d.CreateDivisionStructure();
            Console.ReadLine();
        }
    }

    class division
    {
        private static int CountHowManyTimesMyVarWasInitilized = 0;
        public division()
        {
        }
        protected string _myVar;
        public string myVar
        {
            get
            {
                if (_myVar == null)
                {
                    CountHowManyTimesMyVarWasInitilized++;
                    Console.WriteLine(CountHowManyTimesMyVarWasInitilized);
                    _myVar = "now myVar is not null";
                    return _myVar;
                }
                else
                { return _myVar; }
            }
            set { _myVar = value; }
        }
        public void CreateDivisionStructure()
        {
            Console.WriteLine(myVar);
            for (int i = 0; i < 7; i++)
            {
                Branch b = new Branch(7);
            }
        }
    }   
    class Branch : division
    {
        public Branch(bool dImDerivedClass)
        {
            //  constructor for department to prevent recursive stackoverflow if base of department will call the empty constructor
        }
        public Branch(int NumberOfBranches)
        {
            Console.WriteLine(myVar);
            Department d = new Department(7);
        }
    }

    class Department : Branch
    {

        public Department(bool ImDerivedClass) : base(true)
        {
            //  constructor for team to prevent recursive stackoverflow if base of Team will call the empty constructor
        }
        public Department(int numberOfDep) : base(true)
        {
            for (int i = 0; i < numberOfDep; i++)
            {
                Console.WriteLine(myVar);
                Team t = new Team(7);
            }
        }
    }

    class Team : Department
    {
        public Team(int numberOfTeams) : base(true)
        {
            for (int i = 0; i < numberOfTeams; i++)
            {
                Console.WriteLine(myVar);
            }
        }
    }
}

如何防止派生类的属性的多次初始化

这可能是Lazy<T>类的一个很好的使用,在静态变量中使用,因此进程只有一个副本。在第一次访问变量时,它将运行您给它一次初始化的Func

https://msdn.microsoft.com/en-us/library/dd642331 (v = vs.110) . aspx

然而,基于你的类结构,我不确定这是否是最好的方法。Branch : divisionDepartment : Branch的层次结构的目的是什么?BranchDivision吗?如果您试图共享公共属性,而不是再次编码它们,我建议创建一个公共类,可以保存Branch, DivisionDepartment可以继承的变量。

可以在层次结构中最低的类中使用静态变量/静态构造函数。静态构造函数只被调用一次。

一个简单的解决方案是使用control变量。
我相信你可以改进你的设计,避免这个问题,但我现在没有时间检查。

using System;
namespace Program
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            division d = new division();
            d.CreateDivisionStructure();
            Console.ReadLine();
        }
    }
    internal class division
    {
        private static int CountHowManyTimesMyVarWasInitilized = 0;
        public division()
        {
        }
        protected string _myVar;
        private bool _isReadyForInitialization;
        public string myVar
        {
            get
            {
                if (!_isReadyForInitialization)
                    return null;
                if (_myVar == null)
                {
                    CountHowManyTimesMyVarWasInitilized++;
                    Console.WriteLine(CountHowManyTimesMyVarWasInitilized);
                    _myVar = "now myVar is not null";
                    return _myVar;
                }
                else
                { return _myVar; }
            }
            set { _myVar = value; }
        }
        public void CreateDivisionStructure()
        {
            // now _myVar is spposed to be initilized to all dirved clasess isnt is?
            Console.WriteLine(myVar);
            for (int i = 0; i < 7; i++)
            {
                Branch b = new Branch(7);
            }
            _isReadyForInitialization = true;
            Console.WriteLine(myVar);
        }
    }
    internal class Branch : division
    {
        public Branch(bool dImDerivedClass)
        {
            //  constructor for department to prevent recursive stackoverflow if base of department will call the empty constructor
        }
        public Branch(int NumberOfBranches)
        {
            Console.WriteLine(myVar);
            Department d = new Department(7);
        }
    }
    internal class Department : Branch
    {
        public Department(bool ImDerivedClass) : base(true)
        {
            //  constructor for team to prevent recursive stackoverflow if base of Team will call the empty constructor
        }
        public Department(int numberOfDep) : base(true)
        {
            for (int i = 0; i < numberOfDep; i++)
            {
                Console.WriteLine(myVar);
                Team t = new Team(7);
            }
        }
    }
    internal class Team : Department
    {
        public Team():base(false)
        {
        }
        public Team(int numberOfTeams) : base(true)
        {
            for (int i = 0; i < numberOfTeams; i++)
            {
                Console.WriteLine(myVar);
            }
        }
    }
}