我有一个简化版本,我想在下面做。我有一个由SolarSystem类使用的星球。我想使用foreach循环为SolarSystem中的每个Planet编写orbitTimeInDays。
错误CS1579 foreach语句无法对类型变量进行操作 'TestEnum.SolarSystem'因为'TestEnum.SolarSystem'不包含 'GetEnumerator'的公共定义
问题是枚举,我已经阅读了几篇关于使对象可枚举的文章和问题,但我似乎无法弄清楚如何将它应用于SolarSystem,因此我可以检查它构造的每个星球。 (最终它也将包含小行星等,所以它不仅仅是8个行星和冥王星。)
有人可以帮我理解如何枚举SolarSystem。
class Program
{
static void Main(string[] args)
{
SolarSystem solarSystem = new SolarSystem();
solarSystem.mercury.orbitTimeInDays = 88;
solarSystem.venus.orbitTimeInDays = 225;
// etc...
foreach (Planet planet in solarSystem)
{
Console.WriteLine("Time taken to orbit sun (in days) : " + planet.orbitTimeInDays.ToString());
}
}
}
public class Planet
{
public double distanceFromEarth { get; set; }
public int orbitTimeInDays { get; set; }
// etc...
public Planet() { }
}
public class SolarSystem
{
public Planet mercury { get; set; }
public Planet venus { get; set; }
// etc...
public SolarSystem()
{
mercury = new Planet();
venus = new Planet();
// etc...
}
}
答案 0 :(得分:5)
你的太阳系并没有告诉它可以迭代任何东西。您必须实现IEnumerable
以告诉编译器:
public class SolarSystem : IEnumerable<Planet>
{
public IEnumerator<Planet> GetEnumerator()
{
yield return mercury;
yield return venus;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
这是可枚举的基本实现。它使用yield
关键字为您即时生成枚举器。
或者,您可以在班级中创建一个属性Planets
,可能是这样的:
List<Planet> Planets {get;} = List<Planet>();
然后你可以迭代solarSystem.Planets
。
答案 1 :(得分:2)
您不能只枚举所有属性。也许最好的解决方案是给SolarSystem一个列表或行星词典,所以你可以得到这样的东西:
public class SolarSystem
{
public Dictionary<string, Planet> Planets { get; } = new Dictionary<string, Planet>();
public SolarSystem()
{
Planets.add('Mercury', new Planet());
Planets.add('Venus', new Planet());
// etc...
}
}
然后列举如下:
foreach (Planet planet in solarSystem.Planets.Values)
字典允许您按名称快速查找行星,但如果您不需要,则可以使用List,它只包含没有名称作为键的值(行星)。你可以改名为Planet的一个属性。即使你需要找到一个行星,一个简单的循环来找到它也是好的。毕竟,你不会在太阳系中拥有成千上万的行星,所以不需要大词典更快的搜索机制。
List的一个优点是它保留了添加元素的顺序。 Dictonary没有,虽然还有OrderedDictionary,以防你需要这两个功能。
无论如何,使用这样一个最适合您需求的集合类,可以让您不必自己实现GetEnumerator(来自IEnumerable接口)。
答案 2 :(得分:0)
这不可能像你这样做。您可以创建一个行星列表/数组,而不是为行星创建弹性属性。这样您就可以从solorsystem外部创建新的行星。 ; - )
类似的东西:
public class Planet
{
public double distanceFromEarth { get; set; }
public int orbitTimeInDays { get; set; }
public string name {get; set;}
// etc...
public Planet() { }
}
public class SolarSystem
{
public List<Planet> planets {get; private set;}
public SolarSystem()
{
planets = new List<Planet>();
planets.Add( new Planet { name = "mercury", distanceFromEarth = 23456 });
planets.Add( new Planet { name = "venus", distanceFromEarth = 12456 });
}
}
static void Main(string[] args)
{
SolarSystem solarSystem = new SolarSystem();
foreach (Planet planet in solarSystem.planets)
{
Console.WriteLine("Time taken to orbit sun (in days) : " + planet.orbitTimeInDays.ToString());
}
}
答案 3 :(得分:0)
您正在为每个星球创建对象。 foreach仅适用于收藏。 更好地创造 列出planetList = new List();
并将行星添加到planetList并应用foreach。