我有多维数组。
int[][][] MyValues;
我想要的是通过强类型的equivelent访问索引,例如枚举。我知道你可以从Enum类型中获取枚举值,但是我的口味有点长。
我宁愿有办法强烈输入索引。
例如:
int CarNumber = MyValues[Racetrack.Daytona][Race.Daytona500][Driver.JGordon];
由于它是枚举式的,它可以防止抛出任何越界异常,并且它为所有索引提供了一个很好的人类可读意义。
我已经使用字典方法实现了这一点,但它似乎有点沉重:
Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>> =
new Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>>();
然后我可以通过枚举访问,但我真的不喜欢这种方法。这看起来很“难看”。
我正在寻找一些替代方法,在使用人类可读索引器的同时表示基本上是多维数组,同时保持类型安全性(例如,不能无意中使用Race作为Race)简单地使用consts不是一个好方法。
有什么建议吗?
这将是一个编译时数组(上面的例子不是真实的,只是一个例子)所以我不必担心插入或删除或其他操作数组。它将在价值,大小和布局方面保持不变。
使用带有const值的静态类也不是一个好方法,因为它不强制只定义的值集可以作为索引器传递。
答案 0 :(得分:5)
听起来我想要使用indexers而不是数组。假设以下枚举(基于公式1!):
public enum Track
{
Spielberg,
Adelaide,
Casablanca,
Liverpool,
Melbourne,
Berlin,
Sakhir,
}
public enum Constructor
{
BMW,
Ferrari,
McLaren,
Toyota,
Williams
}
public enum Driver
{
Hamilton,
Kovalainen,
Raikkonen,
Nakajima,
Glock
}
基本结构如下:
public class Race
{
int Year { get; set; }
Track Track { get; set; }
Driver[] Placings { get; set; }
public int this[Driver driver] { } // placing by driver
}
public class Results
{
YearResults this[int index] { }
DriverResults this[Driver index] { }
TrackResults this[Track index] { }
ConstructorResults this[Constructor index] { }
}
public class YearResults
{
YearDriverResults this[Driver index] { }
}
这当然是部分实现,但你可以通过这种方式对索引器做一些非常酷的事情。就像您可以使用任何顺序的任意组合来访问您的信息(假设您设置了所有中间类)。
它比一个多维数组或一个元组键控词典更有语言,但我认为它会给你更优雅的代码。
答案 1 :(得分:2)
如何在<Racetrack,Race,Driver>
中使用三Dictionary
作为键(定义自己的类)?
如果你真的需要使用数组,我认为你不能把它包装在一个自定义类中,只允许使用Racetrack
,Race
,Driver
进行访问枚举。
答案 2 :(得分:0)
明显的问题.. List<T>
不适合你吗?
答案 3 :(得分:0)
枚举是否相当小,值为0 ... n?如果是这样,您可以使用多维数组但公开索引器。请注意,下面的代码使用矩形数组而不是锯齿状数组,但您可以相当容易地调整它。
// In a static class somewhere. Just a convenience method to check
// whether a value is defined or not. See comment in indexer.
public static void CheckDefined<T>(this T value, String name)
where T : struct
{
if (!Enum.IsDefined(typeof(T), value))
{
throw new ArgumentOutOfRangeException(name);
}
}
// Somewhere else...
private static int GetLength<T>() where T : struct
{
return Enum.GetValues(typeof(T)).Length;
}
private int[,,] array = new int[GetLength<Racetrack>(),
GetLength<Race>(),
GetLength<Driver>()];
public int this Car[Racetrack racetrack, Race race, Driver driver]
{
get
{
// If you don't care about just getting an
// IndexOutOfRangeException, you could skip these three lines.
racetrack.CheckDefined("racetrack");
race.CheckDefined("race");
driver.CheckDefined("driver");
return array[(int) racetrack, (int) race, (int) driver);
}
}
答案 4 :(得分:0)
我不认为字典方法不好,但它不优雅。如果您为字典字典创建了别名,那么事情看起来会更好:
using RaceSetup = Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>>;
或者你可以创建一个派生自字典的类:
class RaceSetup : Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>>
{}