我怎样才能修改这段c#代码,使Visual Studio认识到我不是白痴呢?
本文关键字:认识到 Studio Visual 白痴 代码 修改 | 更新日期: 2023-09-27 17:49:18
我有3行
int selectedOrgId;
foreach (Organization o in PD.orgs)
if (o.orgname == selectedOrgName)
selectedOrgId = o.orgid;
PD.cats.InsertOnSubmit(new Category {
orgid = selectedOrgId,
catname = newCatName
});
中间行,即循环,在我的程序的上下文中,保证为selectedOrgId
设置一个值。但是,Visual Studio会标记最后一行,因为
使用未赋值的局部变量'selectedOrgId'
除了
还有什么方法可以解决这个问题?int selectedOrgId = 69;
foreach (Organization o in PD.orgs)
if (o.orgname == selectedOrgName)
selectedOrgId = o.orgid;
PD.cats.InsertOnSubmit(new Category {
orgid = selectedOrgId,
catname = newCatName
});
? ?
虽然它可以工作,但它似乎是一个不优雅的解决方案,因为它涉及到一个神奇的数字。我想知道正确的c#风格来解决这个问题。
编辑:看看这里的一些讨论,我应该指定数据库中只有这样的orgid
。我的foreach
语句应该写成
foreach (Organization o in PD.orgs)
{
if (o.orgname == selectedOrgName)
{
selectedOrgId = o.orgid;
break;
}
}
谢谢你给我展示了一些更好地做这件事的方法!
看起来您正在遍历一个集合,试图根据组织名称找到单个匹配值。您可以使用LINQ的SingleOrDefault()
查找(最多)一个匹配项:
var selectedOrg = PD.orgs.SingleOrDefault(o => o.orgname == selectedOrgName);
如果找到值,则只调用InsertOnSubmit()
: (否则,selectedOrg将为null)
if (selectedOrg != null)
PD.cats.InsertOnSubmit(new Category { orgid = selectedOrg.orgid, catname = newCatName });
不。
如果PD.orgs
中的任何值都不满足o.orgname == selectedOrgName
条件会发生什么?那么selectedOrgId
将保持未初始化。
然而,根据你的方法,下面的代码可能更"优雅":
int selectedOrgId = PD.orgs.Single(o => o.orgname == selectedOrgName).orgid;
PD.cats.InsertOnSubmit(new Category { orgid = selectedOrgId, catname = newCatName });
请注意,您的代码将把selectedOrgId
设置为它的最后一个实例,而我的代码将假设只存在一个。
您可以使用int?
:
int? selectedOrgId = null;
foreach (Organization o in PD.orgs)
{
if (o.orgname == selectedOrgName)
{
selectedOrgId = o.orgid;
}
}
PD.cats.InsertOnSubmit(new Category
{
orgid = selectedOrgId,
catname = newCatName
});
这不是唯一的问题。你知道你会找到一个或多个匹配项,编译器不会。
但是"或更多"也是一个问题。代码只是不清楚你想要什么,这是根本原因。你有一个隐含的"最后一个赢"策略。
当您使用与需求更接近的解决方案时,编译器问题将不需要任何hack而消失。
没有Linq:// int selectedOrgId;
foreach (Organization o in PD.orgs)
if (o.orgname == selectedOrgName)
{
PD.cats.InsertOnSubmit(new Category {
orgid = o.orgid,
catname = newCatName
});
return; // or break;
}
// shouldn't get here
throw new ...
和Linq
Organization org = PD.orgs.Single(o => o.orgname == selectedOrgName);
PD.cats.InsertOnSubmit(new Category {
orgid = selectedOrgId,
catname = newCatName
});
Single(Predicate)
方法与您的问题非常匹配。当结果集有!= 1元素时抛出。
编辑:OP更改了问题,以指定只会找到一个项目,并且不需要多个解决方案,这是选项1a
选项1a -单行Linq方法
这提供了一个单行linq查询,它将过滤掉不必要的组织,抓取单个项目并选择一个新的Category对象作为插入的参数。如果无法定位单个项目,该方法将抛出异常,但这是显式的,根据您的问题应该发生什么。
PD.cats.InsertOnSubmit(
PD.orgs.Where(o=>o.orgname==selectedOrgName)
.Single()
.Select(o=>new Category { orgid = o.orgId, catname = newCatName })
);
选项1b -迭代筛选列表并执行工作
这里的所有其他答案都建议使用linq并假设只会找到一条记录。为什么不直接在循环中执行所有操作,然后使用linq来过滤结果呢?
foreach (Organization o in PD.orgs.Where(o=>o.orgname==selectedOrgName))
{
PD.cats.InsertOnSubmit(new Category { orgid = o.orgId, catname = newCatName });
}
这里的好处是没有if语句,它可以处理单个或多个情况。有一种方法可以在一行上完成此操作,并删除每个的显式并使用List。ForEach(参见比较):
PD.orgs.Where(o=>o.orgname==selectedOrgName).ToList()
.ForEach(o=>PD.cats.InsertOnSubmit(new Category { orgid = o.orgId, catname = newCatName }));
选项2 -使用异常
这将使您的代码意图非常清楚,并让Visual Studio知道您已经注意到了这一点。这样做的目的是让你的代码与现在非常接近:
int selectedOrgId;
foreach (Organization o in PD.orgs)
{
if (o.orgname == selectedOrgName)
selectedOrgId = o.orgid;
}
但是,此时我建议您使用异常,例如:
if(selectedOrgId == 0) throw new InvalidDataException("Selected Org Id cannot be 0");
PD.cats.InsertOnSubmit(new Category { orgid = selectedOrgId, catname = newCatName });
使用linq选择selectedOrgName
的组织并获得orgid
:
PD.cats.InsertOnSubmit(new Category {
orgid = PD.orgs.First(o => o.orgname == selectedOrgName).orgid,
catname = newCatName
});
假设selectedOrgName
将始终在PD.orgs
中,我根据变量名称做出该假设;但是,如果情况并非总是如此,您可以执行以下操作:
var selectedOrg = PD.orgs.FirstOrDefault(o => o.orgname == selectedOrgName);
if (selectedOrg != null)
{
PD.cats.InsertOnSubmit(new Category {
orgid = selectedOrg.orgid,
catname = newCatName
});
}
下面是你的代码所做的完全相同的事情,但是如果你没有匹配的组织(你说不可能发生),它会抛出异常:
PD.cats.InsertOnSubmit(new Category {
orgid = PD.orgs.Last(o => o.orgname == selectedOrgName).orgid,
catname = newCatName
});