Dar*_*olt 1 c# casting type-conversion
我正在Unity3D项目中处理一个C#脚本,我正在尝试获取字符串列表并获得排列的2D列表.以下列方式使用此答案 GetPermutations():
List<string> ingredientList = new List<string>(new string[] { "ingredient1", "ingredient2", "ingredient3" });
List<List<string>> permutationLists = GetPermutations(ingredientList, ingredientList.Count);
Run Code Online (Sandbox Code Playgroud)
但它会引发隐式转换错误:
IEnumerable<IEnumerable<string>> to List<List<string>> ... An explicit conversion exists (are you missing a cast)?
所以我看了几个地方,比如这里,并提出了以下修改:
List<List<string>> permutationLists = GetPermutations(ingredientList, ingredientList.Count).Cast<List<string>>().ToList();
Run Code Online (Sandbox Code Playgroud)
但它在运行时中断,在内部处理,并允许它继续而不指示失败 - 可能是因为它在Unity3D中运行.这是我在停止调试脚本后在Unity3D中看到的内容:
InvalidCastException: Cannot cast from source type to destination type.
System.Linq.Enumerable+<CreateCastIterator>c__Iterator0`1[System.Collections.Generic.List`1[System.String]].MoveNext ()
System.Collections.Generic.List`1[System.Collections.Generic.List`1[System.String]].AddEnumerable (IEnumerable`1 enumerable) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:128)
System.Collections.Generic.List`1[System.Collections.Generic.List`1[System.String]]..ctor (IEnumerable`1 collection) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:65)
System.Linq.Enumerable.ToList[List`1] (IEnumerable`1 source)
Run Code Online (Sandbox Code Playgroud)
我认为这仍然是错误的,所以我也尝试了以下方法和更多我不记得的方法:
List<List<string>> permutationLists = GetPermutations(ingredientList, ingredientList.Count).Cast<List<List<string>>>();
List<List<string>> permutationLists = GetPermutations(ingredientList.AsEnumerable(), ingredientList.Count);
Run Code Online (Sandbox Code Playgroud)
以及在方法调用之前使用括号显式转换,就像在C或Java中一样,仍然无济于事.
那么我应该如何从GetPermutations()函数中转换结果来得到一个List<List<string>>?或者,我怎么能修改函数只返回,List<List<string>>因为我不需要它为泛型类型工作?我尝试自己修改方法如下:
List<List<string>> GetPermutations(List<string> items, int count)
{
int i = 0;
foreach(var item in items)
{
if(count == 1)
yield return new string[] { item };
else
{
foreach(var result in GetPermutations(items.Skip(i + 1), count - 1))
yield return new string[] { item }.Concat(result);
}
++i;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,<T>从函数名中删除它后,它断言主体不能是迭代器块.我没有C#的经验,而且我在强类型语言中使用模板函数生锈,所以任何解释/帮助都是值得赞赏的.
我不确定如何看待这个问题,所以如果这是一个重复只是发布在这里,我会立即删除这个帖子.
那么我应该如何从GetPermutations()函数中转换结果来获取a
List<List<string>>
最佳解决方案:不要.为什么需要首先将序列转换为列表?将其保留为序列序列.
如果你必须:
GetPermutations(...).Select(s => s.ToList()).ToList()
Run Code Online (Sandbox Code Playgroud)
如果要修改原始方法,只需执行相同的操作:
IEnumerable<List<string>> GetPermutations(List<string> items, int count)
{
int i = 0;
foreach(var item in items)
{
if(count == 1)
yield return new List<T>() { item };
else
{
foreach(var result in GetPermutations(items.Skip(i + 1), count - 1))
yield return (new string[] {item}.Concat(result)).ToList();
}
++i;
}
}
Run Code Online (Sandbox Code Playgroud)
然后做GetPermutations(whatever).ToList(),你有一个列表清单.但同样,不要这样做.如果可能,请将所有内容保持在序列中.
我想将序列转换为一个列表,以便我可以按字母顺序对元素进行排序,并将它们重新连接为一个排序的,单个逗号分隔的字符串.
好的,然后那样做.让我们将您的方法重写为扩展方法Permute().让我们制作一些新的单线方法:
static public string CommaSeparate(this IEnumerable<string> items) =>
string.Join(",", items);
static public string WithNewLines(this IEnumerable<string> items) =>
string.Join("\n", items);
static public IEnumerable<string> StringSort(this IEnumerable<string> items) =>
items.OrderBy(s => s);
Run Code Online (Sandbox Code Playgroud)
然后我们有以下内容 - 我将对这些类型进行注释:
string result =
ingredients // List<string>
.Permute() // IEnumerable<IEnumerable<string>>
.Select(p => p.StringSort()) // IEnumerable<IEnumerable<string>>
.Select(p => p.CommaSeparate())// IEnumerable<string>
.WithNewLines(); // string
Run Code Online (Sandbox Code Playgroud)
我们已经完成了. 看看代码在做出一件事并做得好的方法时是多么清晰明了.看看按顺序保存所有内容是多么容易.
| 归档时间: |
|
| 查看次数: |
662 次 |
| 最近记录: |