我有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;
}
}
感谢您向我展示了一些更好地完成这一切的方法!
答案 0 :(得分:4)
您似乎正在迭代集合,尝试根据组织名称查找单个匹配值。您可以使用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 });
答案 1 :(得分:3)
否强>
如果o.orgname == selectedOrgName
中的任何值都不满足条件PD.orgs
会怎样?然后selectedOrgId
将保持未初始化状态。
但是,以下代码可能更加优雅'根据你的方法:
int selectedOrgId = PD.orgs.Single(o => o.orgname == selectedOrgName).orgid;
PD.cats.InsertOnSubmit(new Category { orgid = selectedOrgId, catname = newCatName });
请注意,您的代码会将selectedOrgId
设置为最后一个实例,而我的代码将假设只存在一个。
答案 2 :(得分:2)
您可以使用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
});
:
Rooms
.ForEach(room => room.RoomContents.ForEach(roomContents =>
{
Console.WriteLine("The commands for {0}",roomContents.Name);
roomContents.SupportedCommands.ForEach(command =>
Console.Writeline("{0}",command))
}));
Console.ReadLine();
答案 3 :(得分:2)
编辑:OP更改了问题以指定只找到一个项目并且不需要多个解决方案,这里是选项1a
选项1a - 一行Linq方法
这提供了单行linq查询,它将过滤掉不必要的orgs,获取单个项目并选择一个新的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 if语句,它处理单个或多个案例。有一种方法可以在一行中创建它并删除每个的显式并使用List.ForEach(see the comparisons):
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 });
答案 4 :(得分:2)
这不是唯一的问题。你知道你会发现一个或多个匹配,编译器没有。
但“或更多”也是一个问题。代码只是不清楚你想要什么,这是根本原因。你有一个隐含的“最后一个胜利”战略。
当您使用更符合要求的解决方案时,编译器问题就会消失而没有任何黑客攻击。
没有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元素时,它将抛出。
答案 5 :(得分:1)
使用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
});
}
答案 6 :(得分:1)
以下内容完全等同于您的代码所做的事情,但如果您没有匹配的组织(您说不会发生),它会抛出异常:
PD.cats.InsertOnSubmit(new Category {
orgid = PD.orgs.Last(o => o.orgname == selectedOrgName).orgid,
catname = newCatName
});