我正在对现有的ASP.NET MVC应用程序中的函数进行一些重构,并且在控制器中遇到了以下小的递归函数。我对C#和.NET还是有点陌生,所以如果我发现错误,请多多包涵。
private int _bl;
[Session]
public void TotalMaterialSubCategories(IEnumerable<Category> materialMasterCats, int i)
{
foreach (var materialMasterCat in materialMasterCats)
{
_bl = _bl + 1;
materialMasterCat.Level = i;
if (materialMasterCat.ChildCategories.Count != 0)
{
TotalMaterialSubCategories(materialMasterCat.ChildCategories.ToList(), i + 1);
if (materialMasterCat.Parent == 0)
{
materialMasterCat.SortOrder = _bl;
_bl = 0;
}
}
}
}
与我有关的事情是这个private int _bl
声明。在该类中,对此变量的唯一引用与该函数关联。
我认为_b1 = _b1 + 1
行可能不可靠,因为它没有手动初始化。不过,我认为,由于它是int
,因此它不能为null或保留为“未初始化”,因此它的默认值为0; corroborated by the MS Docs。递归看起来像气泡一样,这使我认为在此函数调用结束时也将其设置回0。最后,我非常确定每个独立的Web请求都将获得该控制器的单独实例,因此看起来它的编写方式应该可以按预期运行。
但是,我只是想知道为什么会这样写。是否有一个原因,这不仅是函数初始化为0的局部变量?您可以在控制器中的函数之间依赖局部私有变量吗?另外,我的任何假设/决定都不正确吗?
答案 0 :(得分:2)
我相信,由于它是一个整数,因此不能为null或保留 '未初始化',因此它的默认值为0;被证实 MS文档
尝试将private int _bl;
作为int _bl;
放入函数中,您会看到编译错误,因为您无法对未初始化的值执行_bl = _bl + 1;
操作。因此,它不会在函数范围内自动初始化,但是当它是类实例的属性时,它确实会自动初始化。
有关何时分配值和何时不分配值的更多信息,请参见:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/variables这种特殊情况属于:
一个类的实例变量来了 当创建该类的新实例时就存在了,并且 当没有引用该实例且 实例的析构函数(如果有)已执行。的初始值 类的实例变量是的默认值(Default values) 变量的类型。为了进行明确的分配检查, 一个类的实例变量被认为是最初分配的。
答案 1 :(得分:2)
与我有关的事情是这个私有的int _bl语句。在该类中,对此变量的唯一引用与该函数关联。
很显然,我们看不到所有代码,但是如果我相信您此Field(非变量)仅由该函数引用,那么我想如果有其他方法可以保留它已经引用了它,现在这些方法不再存在,使用了它,或者方法使用它来维护状态,而不执行任何单个方法(事件或属性)。
递归看起来像气泡一样,使我认为在此函数调用结束时也将其设置回0。
设置为零 before the constructor is called。
不一定。在该类的每个实例化方法if (materialMasterCat.Parent == 0)
结束后,只能 重新设置为零。
因为控制器不是静态类,所以每个创建的类都有其自己的私有版本_bl
,该类只能(通常)由类本身(private access modifer)访问。
但是,我只是想知道为什么会这样写。是不是因为它不仅仅是函数的局部变量(以0初始化)?
因为这段代码运行时,它们的值均为1:
materialMasterCat.SortOrder = _bl;
但是发生的事情是,每次调用该函数时,它都会递增,因为它存在于类的作用域中,而不是存在于函数scope中。
您可以在MVC控制器中的函数之间依赖局部私有变量吗?
私有变量始终可用,直到一个类(通常)被处理为止,这一次被称为对象的Lifetime。