.net c#在集合初始化器中使用条件

Using a condition within a collection initializer
2021-03-07
  •  译文(汉语)
  •  原文(英语)

我有一些要输入到词典中的值:

// Pretend these values are retrieved from a database or something
string firstName = "John";
string lastName = "Smith";

List<string> listHobbies = new List<string> () {"hockey","soccer"};

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", listHobbies}
};

但是,在某些情况下,List<string>变量可能是一个空列表.如果是这种情况,我不想将{"hobbies", listHobbies}键添加到结果字典中.

有没有一种方法可以在字典的集合初始化程序中实现此检查?还是我坚持使用if语句检查列表的大小并在声明后立即删除键?

编辑:本质上,我想知道C#是否允许这样的事情:

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", listHobbies} unless (listHobbies.Count == 0) // don't add the "hobbies" key if the list is empty.
};

我目前可以通过执行以下操作来实现此目的:

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", listHobbies}
};
}.Concat(listHobbies != 0 ? new Dictionary<string, dynamic>() { { "hobbies", listHobbies } } : new Dictionary<string, dynamic>()).ToDictionary(k => k.Key, v => v.Value);

但这真是丑陋.

编辑2: 我发现了一个可以接受的解决方案,如果其他人可以提供更好的替代方案,请随时提出以下建议:

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", !listHobbies.Any() ? listHobbies : null}
}
.Where(entry => entry.Value != null)
.ToDictionary(k => k.Key, v => v.Value);
速聊1:
如何检查是否(listHobbies.Count()> 0)
速聊2:
是的,我可以在Dictionary声明之前或之后检查该条件,然后相应地删除(或只是不添加)键,但是为了寻找干净的代码,我正在寻找一种在字典初始化中执行此操作的方法.
速聊3:
我有一种感觉,将条件放在集合初始化器中可能是不好的做法.我们在确定值时使用集合初始值设定项,在其他情况下,建议使用条件循环进行循环.Where(x => x!= null)将导致整个集合再次进行空检查.
速聊4:
我得到的感觉是,您不需要Dictionary <string,dynamic>.您需要一个具有3个属性的对象:firstName,lastName和hobby.然后,您可以将该对象填充到Dictionary或其他集合中.
解决过程1

这怎么了

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName}
};
if (listHobbies.Any())
    dict.Add("hobbies", listHobbies);
速聊1:
它在声明后对集合进行了变异,这是我试图避免的事情.但是,我现在想用C#来完成的工作似乎并不可行,但是我想我已经找到了一个更好看的选择,它将在一分钟内编辑OP.
速聊2:
为什么不只将突变部分移动到方法中,并将dict设为只读,这样您仍然可以保持不变性.初始化后不应该更改集合的任何特定原因吗?
速聊3:
没什么特别的原因,我一直在学习函数式编程原理并将其应用于我的其他项目,用C#来做到这一点可能不是最佳实践,因为C#并不是出于这样的考虑而创建的(想像).尽管如此,我只是好奇这是否可行.

I have a few values that I want to put into a Dictionary:

// Pretend these values are retrieved from a database or something
string firstName = "John";
string lastName = "Smith";

List<string> listHobbies = new List<string> () {"hockey","soccer"};

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", listHobbies}
};

However, in some instances, the List<string> variable may be an empty list. If this is the case, I do not want to add the {"hobbies", listHobbies} key to the resulting dictionary.

Is there a way to implement this check within the collection initializer of the dictionary? or am I stuck using an if statement to check the size of the list and remove the key immediately after the declaration?

Edit: Essentially, I am wondering if C# allows something like this:

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", listHobbies} unless (listHobbies.Count == 0) // don't add the "hobbies" key if the list is empty.
};

I can currently achieve this by doing something like this:

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", listHobbies}
};
}.Concat(listHobbies != 0 ? new Dictionary<string, dynamic>() { { "hobbies", listHobbies } } : new Dictionary<string, dynamic>()).ToDictionary(k => k.Key, v => v.Value);

But this is incredibly ugly.

Edit 2: I've found a somewhat acceptable solution, if anyone else can offer a nicer looking alternative, feel free to suggest:

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName},
    {"hobbies", !listHobbies.Any() ? listHobbies : null}
}
.Where(entry => entry.Value != null)
.ToDictionary(k => k.Key, v => v.Value);
Talk1:
how about checking if (listHobbies.Count() > 0)
Talk2:
yes I can check that condition either before or after the Dictionary declaration and remove (or just not add) the key accordingly, however I am looking for a way to do this within the dictionary's initialization for the sake of clean code.
Talk3:
I've got a feeling that putting a conditional in a collection initalizer might be bad practice. we use collection initializers when we are sure of the values, in other cases it might be more advisable to run a loop with conditional. The Where(x=>x!=null) will cause the whole collection to be iterated again for the null check.
Talk4:
The feeling i get is that you don't need a Dictionary<string, dynamic>. You need an object that has 3 properties: firstName, lastName and hobbies. You can then stuff this object into a Dictionary or some other collection.
Solutions1

What's wrong with this?

var dict = new Dictionary<string, dynamic>() 
{
    {"firstName", firstName},
    {"lastName", lastName}
};
if (listHobbies.Any())
    dict.Add("hobbies", listHobbies);
Talk1:
It mutates the collection after declaration, which is something I was trying to avoid. What I'm trying to do however doesn't appear to be currently possible in C#, but I think I have found a nicer looking alternative, will edit the OP in a minute.
Talk2:
why not just move the mutation part into a method so and make the dict readonly thus you will still be able to maintain immutability. Is there any specific reason why the collection should not be changed after initalisation?
Talk3:
No particular reason, I've been learning about functional programming principles and trying to apply them to my other projects, it's probably not best practice to do it like this in C#, a language that wasn't created with such things in mind (I imagine). Nonetheless, I was just curious if this was possible.
转载于:https://stackoverflow.com/questions/23003237/using-a-condition-within-a-collection-initializer

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入