在C#中将List<dynamic>转换为List<string>

39

假设我有一个包含字符串的List<dynamic>对象:

var dlist = new List<dynamic>()
{
    "test",
    "test2",
    "test3"
};

有没有一种有效的方法将这个列表转换为一个正确的List<string>对象?我知道我可以遍历这个列表并将每个元素强制转换为字符串,然后将其添加到结果列表中,但也许一些Linq魔法可以在一行中完成这个任务?

我尝试使用一些结合了Select()ToList()Cast<string>的语句,但是都没有成功。应该如何正确地完成这个任务呢?

注意:通过说“有效”,我当然是指代码行数。我不考虑执行时间或性能。而且——假设我不需要类型检查,在这个动态列表中始终只有字符串。

编辑:好吧,关于“为什么转换失败”的评论——看起来我有另一个问题,关于我接收到的数据(我正在使用Dapper),所以它没有起作用。对于造成的困惑,我很抱歉,我原本以为我的列表转换出了问题,但实际上与此无关。


7
只需要使用 dlist.Cast<string>().ToList(); 即可。 - Evk
5
既然你知道类型,为什么一开始还要使用“dynamic”呢? - MakePeaceGreatAgain
我很想知道你所说的“但徒劳无功”是什么意思。发生了什么事情? - LordWilmore
你还没有澄清“不起作用”是什么意思。在这个问题上,你的实际问题是什么? - MakePeaceGreatAgain
@HimBromBeere 我已经这样做了。它按预期工作,我遇到的问题与转换无关,这误导了我认为我在转换部分做错了什么。我认为这个问题可以保留作为将动态列表转换为给定类型列表的正确引用,不是吗? - Asunez
显示剩余2条评论
2个回答

73

鉴于

var dList = new List<dynamic>() { /*...initialize list */ };

如果您想提取集合中的所有字符串,而忽略其他类型,则可以使用:

// Solution 1: Include only strings, no null values, no exceptions thrown
var strings = dlist.OfType<string>().ToList();

如果您确定列表中的所有项都是字符串(如果它们不是,则会抛出异常),则可以使用:

// Solution 2: Include strings with null values, Exception for other data types thrown
var strings = dlist.Cast<string>().ToList();

如果您想要列表中所有项目的默认字符串表示形式,并且对于null值使用null,则可以使用以下代码:
// Solution 3: Include all, regardless of data type, no exceptions thrown
var strings = dlist.Select(item => item?.ToString()).ToList();

2
或者 dlist.Cast<string>()。但是既然 OP 已经尝试过了,知道为什么它不起作用会很有趣。如果列表中有其他类型,而 OP 没有提到,那么 OfType 就会派上用场。 - Tim Schmelter
@AlexC. boxing/unboxing 是针对 object 而不是 dynamic 的。但是,您是正确的,OfType 将仅返回实际的 string,而如果存在非 string 值,则 Cast 将失败。 - Camilo Terevinto
如果Eric Lippert在动态类型和对象类型方面是错误的,我不知道谁会是正确的:https://dev59.com/B2445IYBdhLWcg3wXZS9 - Alexandru Clonțea
这是我问题的完美且最简单的解决方案。 - Thameem
1
好的回答。让我补充一些内容:解决方案1仅返回字符串类型的项,将抑制空值和数字。解决方案2包括空值,但如果有数字,则会引发异常。解决方案3适用于所有类型,包括空值和数字(在使用LinqPad 6测试了.NET Core)。 - Matt
显示剩余4条评论

36

这个答案是关于 dart/flutter 的。

给定

List<dynamic> dList;

您可以使用

var sList = List<String>.from(dlist);

List<dynamic> 转换为 List<String>


1
.from(...) 对我不起作用。我在 LinqPad 中尝试了一下。有什么遗漏吗?(使用...) - Matt
1
好久没解析了,完全忘记了!谢谢!!! 哈哈,这是C#部分,这是dart语法,它把我带到这里!!! 难怪它有这么多点赞,可能来自dart/flutter的人。 - serg
1
@serg 我得到了 错误 CS0117:'List<string>' 不包含 'from' 的定义 - tmt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接