How can I modify this C# code so that Visual Studio recognizes that I'm not an idiot?
我有三条线
1 2 3 4 5 6 7 8 9 10 | int selectedOrgId; foreach (Organization o in PD.orgs) if (o.orgname == selectedOrgName) selectedOrgId = o.orgid; PD.cats.InsertOnSubmit(new Category { orgid = selectedOrgId, catname = newCatName }); |
在我的程序环境中,中间一行(循环)被保证为
Use of unassigned local variable 'selectedOrgId'
除了
1 2 3 4 5 6 7 8 9 10 | 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 }); |
?????
虽然它是有效的,但它似乎是一个不雅的解决方案,因为它涉及一个神奇的数字。我想知道解决这个问题的正确方式。
编辑:
看看这里的讨论,我应该指定数据库中只有这样的
1 2 3 4 5 6 7 8 | foreach (Organization o in PD.orgs) { if (o.orgname == selectedOrgName) { selectedOrgId = o.orgid; break; } } |
谢谢你给我介绍了一些更好地完成这整件事的方法!
您似乎在迭代一个集合,试图根据组织名称找到一个匹配的值。您可以使用Linq的
1 | var selectedOrg = PD.orgs.SingleOrDefault(o => o.orgname == selectedOrgName); |
然后,只有在找到值时才调用
1 2 | if (selectedOrg != null) PD.cats.InsertOnSubmit(new Category { orgid = selectedOrg.orgid, catname = newCatName }); |
不。
如果条件
但是,根据您的方法,以下代码可能更"优雅":
1 2 | int selectedOrgId = PD.orgs.Single(o => o.orgname == selectedOrgName).orgid; PD.cats.InsertOnSubmit(new Category { orgid = selectedOrgId, catname = newCatName }); |
请注意,您的代码将把
这不是唯一的问题。你知道你会找到一个或多个匹配项,编译器不会。
但"或更多"也是一个问题。代码只是不清楚你想要什么,这是根本原因。你有一个隐含的"最后一个胜利"策略。
当您使用一个更接近需求的解决方案时,编译器问题会消失,不会有任何黑客攻击。
没有LINQ:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
和LINQ
1 2 3 4 5 | Organization org = PD.orgs.Single(o => o.orgname == selectedOrgName); PD.cats.InsertOnSubmit(new Category { orgid = selectedOrgId, catname = newCatName }); |
编辑:op更改了问题,指定只找到一个项目,不需要多个解决方案,这里是选项1a。
方案1a-单线直线法
这提供了一个单行的LINQ查询,它将过滤掉不必要的组织,获取单个项目,并选择一个新的类别对象作为插入的参数。如果找不到单个项,则此方法将引发异常,但也就是说,根据您的问题应该发生什么。
1 2 3 4 5 | PD.cats.InsertOnSubmit( PD.orgs.Where(o=>o.orgname==selectedOrgName) .Single() .Select(o=>new Category { orgid = o.orgId, catname = newCatName }) ); |
选项1b-迭代筛选列表并执行工作
这里的所有其他答案都建议使用LINQ,并假设只会找到一个记录。为什么不做循环中的所有事情,并使用LINQ过滤结果呢?
1 2 3 4 | foreach (Organization o in PD.orgs.Where(o=>o.orgname==selectedOrgName)) { PD.cats.InsertOnSubmit(new Category { orgid = o.orgId, catname = newCatName }); } |
这里的好处是没有if语句,它可以处理单个或多个案例。有一种方法可以在一行中进行此操作,并删除explicit for each和use list.for each(请参见比较):
1 2 | PD.orgs.Where(o=>o.orgname==selectedOrgName).ToList() .ForEach(o=>PD.cats.InsertOnSubmit(new Category { orgid = o.orgId, catname = newCatName })); |
选项2-使用异常
这将使代码意图非常清楚,并让Visual Studio知道您已经处理好了这一点。我们的想法是让您的代码非常接近现在的状态:
1 2 3 4 5 6 | int selectedOrgId; foreach (Organization o in PD.orgs) { if (o.orgname == selectedOrgName) selectedOrgId = o.orgid; } |
但是,此时我建议您使用一个例外,例如:
1 2 |
您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 }); |
下面的代码与您的代码所做的完全相同,但如果您没有匹配的组织(您认为不可能发生),则会引发异常:
1 2 3 4 | PD.cats.InsertOnSubmit(new Category { orgid = PD.orgs.Last(o => o.orgname == selectedOrgName).orgid, catname = newCatName }); |
使用linq选择带
1 2 3 4 | PD.cats.InsertOnSubmit(new Category { orgid = PD.orgs.First(o => o.orgname == selectedOrgName).orgid, catname = newCatName }); |
假设
1 2 3 4 5 6 7 8 9 | var selectedOrg = PD.orgs.FirstOrDefault(o => o.orgname == selectedOrgName); if (selectedOrg != null) { PD.cats.InsertOnSubmit(new Category { orgid = selectedOrg.orgid, catname = newCatName }); } |