我怎样才能修改这段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;
    }
 }

谢谢你给我展示了一些更好地做这件事的方法!

我怎样才能修改这段c#代码,使Visual Studio认识到我不是白痴呢?

看起来您正在遍历一个集合,试图根据组织名称找到单个匹配值。您可以使用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
});