C#,将 case 语句转换为 yield 语句
C#, converting a case statement to a yield statement
我想使用 yield 关键字将这个用于构建 VM 映像列表以用于测试的语句转换为更优雅的内容,但我看不懂语法。
期望的最终目标。
List<VmImages> images;
images[0] - WindowsServer2019
images[1] - WindowsServer2016
images[2] - RhelServer;
images[3] - OpenLogic;
今天的代码如下所示:
for (var i = 0; i < LinuxVMs; i++)
{
switch (i)
{
case 0:
linuxDistros.Add(ConfigLoader.redHat);
break;
case 1:
linuxDistros.Add(ConfigLoader.openLogic);
break;
case 2:
linuxDistros.Add(ConfigLoader.suse);
break;
case 3:
linuxDistros.Add(ConfigLoader.ubuntu);
break;
}
}
这感觉是一个很好的例子,可以使用 yield 关键字将逻辑简化为这样的东西,其中我调用 GetLinuxVMs()
x 次,其中 X 是 LinuxVMs
的计数.
private static IEnumerable<VmDistribution> GetLinuxVmDistros()
{
yield return ConfigLoader.redHat;
yield return ConfigLoader.openLogic;
yield return ConfigLoader.suse;
yield return ConfigLoader.canonical;
}
我不确定如何将其集成到我的代码中,这是我尝试过的方法:
for (var i = 0; i < LinuxVMs; i++)
{
linuxDistros.Add(GetLinuxVmDistros());
}
因为我每次都从 GetLinuxVmDistros
方法中得到一个 IEnum,所以我对它应该如何工作感到困惑。
根据您所说的“期望的最终目标”
List<VmImages> images = new() {
WindowsServer2019,
WindowsServer2016,
RhelServer,
OpenLogic
}
所有其他 looping/finagling 只是混淆了问题,恕我直言
根据您的定义,GetLinuxVmDistros()
将 return 变成 IEnumerable<VmDistribution>
。
您似乎想向名为 linuxDistros
的集合添加另一个集合。
如果linuxDistros
是List<VmDistribution>
,只需使用AddRange
方法:
linuxDistros.AddRange(GetLinuxVmDistros());
参见:https://docs.microsoft.com/fr-fr/dotnet/api/system.collections.generic.list-1.addrange?view=net-6.0
但我看不出为此创建 Enumerable 的意义。
我不确定你试图实现什么,因为命名是..不清楚。但是使用下面的代码,它可以工作:
class ConfigLoader
{
static public VmDistribution redHat { get; set; } = VmDistribution.a;
static public VmDistribution openLogic { get; set; } = VmDistribution.b;
static public VmDistribution suse { get; set; } = VmDistribution.c;
static public VmDistribution canonical { get; set; } = VmDistribution.d;
}
enum VmDistribution { a, b, c, d }
IEnumerable<VmDistribution> GetLinuxVmDistros()
{
yield return ConfigLoader.redHat;
yield return ConfigLoader.openLogic;
yield return ConfigLoader.suse;
yield return ConfigLoader.canonical;
}
var list = new List<VmDistribution>();
list.AddRange(GetLinuxVmDistros());
请注意,最后我只调用了一次 GetLinuxVmDistros()
,并且列表中充满了方法 list.AddRange()
。
在您的示例中,您应该使用循环对项目执行任何需要执行的操作。
for (var i = 0; i < LinuxVMs; i++)
{
ProcessItem(LinuxVMs[i]);
}
话虽如此,在这么小的一组结果上屈服并没有多大意义。 yield return
的主要目的是允许大型集合一次返回 1 个项目,调用代码可能希望在任何时候停止迭代这些项目。另一种用法是一次获取所有项目在资源方面可能非常昂贵。
例如,如果出于某种原因无法处理 1 项,您可能不想继续。
for (var i = 0; i < LinuxVMs; i++)
{
var result = ProcessItem(LinuxVMs[i]);
if (!result.Success)
{
break;
}
}
但是,如果您只需要列表中的项目,那么请忘记所有这些,直接创建包含其中项目的列表:
var images =
new List<VmImages>
{
WindowsServer2019,
WindowsServer2016,
RhelServer,
OpenLogic
};
我想使用 yield 关键字将这个用于构建 VM 映像列表以用于测试的语句转换为更优雅的内容,但我看不懂语法。
期望的最终目标。
List<VmImages> images;
images[0] - WindowsServer2019
images[1] - WindowsServer2016
images[2] - RhelServer;
images[3] - OpenLogic;
今天的代码如下所示:
for (var i = 0; i < LinuxVMs; i++)
{
switch (i)
{
case 0:
linuxDistros.Add(ConfigLoader.redHat);
break;
case 1:
linuxDistros.Add(ConfigLoader.openLogic);
break;
case 2:
linuxDistros.Add(ConfigLoader.suse);
break;
case 3:
linuxDistros.Add(ConfigLoader.ubuntu);
break;
}
}
这感觉是一个很好的例子,可以使用 yield 关键字将逻辑简化为这样的东西,其中我调用 GetLinuxVMs()
x 次,其中 X 是 LinuxVMs
的计数.
private static IEnumerable<VmDistribution> GetLinuxVmDistros()
{
yield return ConfigLoader.redHat;
yield return ConfigLoader.openLogic;
yield return ConfigLoader.suse;
yield return ConfigLoader.canonical;
}
我不确定如何将其集成到我的代码中,这是我尝试过的方法:
for (var i = 0; i < LinuxVMs; i++)
{
linuxDistros.Add(GetLinuxVmDistros());
}
因为我每次都从 GetLinuxVmDistros
方法中得到一个 IEnum,所以我对它应该如何工作感到困惑。
根据您所说的“期望的最终目标”
List<VmImages> images = new() {
WindowsServer2019,
WindowsServer2016,
RhelServer,
OpenLogic
}
所有其他 looping/finagling 只是混淆了问题,恕我直言
GetLinuxVmDistros()
将 return 变成 IEnumerable<VmDistribution>
。
您似乎想向名为 linuxDistros
的集合添加另一个集合。
如果linuxDistros
是List<VmDistribution>
,只需使用AddRange
方法:
linuxDistros.AddRange(GetLinuxVmDistros());
参见:https://docs.microsoft.com/fr-fr/dotnet/api/system.collections.generic.list-1.addrange?view=net-6.0
但我看不出为此创建 Enumerable 的意义。
我不确定你试图实现什么,因为命名是..不清楚。但是使用下面的代码,它可以工作:
class ConfigLoader
{
static public VmDistribution redHat { get; set; } = VmDistribution.a;
static public VmDistribution openLogic { get; set; } = VmDistribution.b;
static public VmDistribution suse { get; set; } = VmDistribution.c;
static public VmDistribution canonical { get; set; } = VmDistribution.d;
}
enum VmDistribution { a, b, c, d }
IEnumerable<VmDistribution> GetLinuxVmDistros()
{
yield return ConfigLoader.redHat;
yield return ConfigLoader.openLogic;
yield return ConfigLoader.suse;
yield return ConfigLoader.canonical;
}
var list = new List<VmDistribution>();
list.AddRange(GetLinuxVmDistros());
请注意,最后我只调用了一次 GetLinuxVmDistros()
,并且列表中充满了方法 list.AddRange()
。
在您的示例中,您应该使用循环对项目执行任何需要执行的操作。
for (var i = 0; i < LinuxVMs; i++)
{
ProcessItem(LinuxVMs[i]);
}
话虽如此,在这么小的一组结果上屈服并没有多大意义。 yield return
的主要目的是允许大型集合一次返回 1 个项目,调用代码可能希望在任何时候停止迭代这些项目。另一种用法是一次获取所有项目在资源方面可能非常昂贵。
例如,如果出于某种原因无法处理 1 项,您可能不想继续。
for (var i = 0; i < LinuxVMs; i++)
{
var result = ProcessItem(LinuxVMs[i]);
if (!result.Success)
{
break;
}
}
但是,如果您只需要列表中的项目,那么请忘记所有这些,直接创建包含其中项目的列表:
var images =
new List<VmImages>
{
WindowsServer2019,
WindowsServer2016,
RhelServer,
OpenLogic
};