如何防止派生类的属性的多次初始化
本文关键字:初始化 属性 派生 何防止 | 更新日期: 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 : division
和Department : Branch
的层次结构的目的是什么?Branch
是Division
吗?如果您试图共享公共属性,而不是再次编码它们,我建议创建一个公共类,可以保存Branch
, Division
和Department
可以继承的变量。
可以在层次结构中最低的类中使用静态变量/静态构造函数。静态构造函数只被调用一次。
一个简单的解决方案是使用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);
}
}
}
}