如何修改此C#代码以便Visual Studio认识到我不是白痴?

时间:2015-05-14 17:13:31

标签: c# linq

我有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;
    }
 }

感谢您向我展示了一些更好地完成这一切的方法!

7 个答案:

答案 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
});