我明白我想要做的事情有点像黑客,但它仍然很有趣。
我的情况很可能是数组可能没有我期望的那么多项目。
这是概念:
namespace TESTAPP
{
class Program
{
static void Main(string[] args)
{
string derp = "foooooo";
//The split is important, you might not have the character there to split by
Writer(derp.Split('x')[0] ?? ".");
Writer(derp.Split('x')[1] ?? ".");
}
private static void Writer(string writeme)
{
Console.WriteLine(writeme ?? "..");
}
}
}
当然,在执行上述打印时我并不太感到惊讶:
foooooo
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at TESTAPP.Program.Main(String[] args) in [snip]\TESTAPP\Program.cs:line 15
我应该如何逻辑地处理这种情况? try/catch
块看起来有点矫枉过正。
答案 0 :(得分:2)
首先,您只需要拆分一次,而不是再次拆分每个部分:
string derp = "foooooo";
string[] parts = derp.Split('x');
// parts == { "foooooo" }
// parts.Length == 1
现在您有一个包含许多部分的数组,因此您只需在访问每个部分之前检查Length
属性:
Writer(parts.Length > 0 ? parts[0] : ".");
Writer(parts.Length > 1 ? parts[1] : ".");
Writer(parts.Length > 2 ? parts[2] : ".");
Writer(parts.Length > 3 ? parts[3] : ".");
Writer(parts.Length > 4 ? parts[4] : ".");
或
for (int i = 0; i < 5; i++)
{
Writer(parts.Length > i ? parts[i] : ".");
}
输出:
foooooo..
...
...
...
...
答案 1 :(得分:1)
在这个具体的例子中..迭代结果:
foreach (var item in derp.Split('x'))
Writer(item);
如果还有其他具体案例......那么这显然可能不符合您的要求。
答案 2 :(得分:1)
只需适当更改条件,不要尝试全部内联:
var split = derp.Split('x');
Writer(split.Length >= 2 ? split[1] : ".");
如果输入中存在大量此类条件并且每个条件默认为不同的值,则可以预先调整数组的大小:
var split = derp.Split('x');
Array.Resize(ref split, 2);
Writer(split[1] ?? "."); // this is now safe
请注意,上面的内容看起来很糟糕,因为[1]
没有说明该数组元素的内容,因此默认为"."
的原因可能并不明显。
答案 3 :(得分:1)
定义GetOrDefault
扩展方法,如下所示:
// If you need this method to work with collections or even IEnumerables,
// you can change implementation to get the count differently.
// This should be sufficient for arrays, though:
static T GetOrDefault(this T[] items, int index) {
return items.Length > index ? items[index] : default(T);
}
现在您可以按如下方式使用此方法:
Writer(derp.Split('x').GetOrDefault(0) ?? ".");
Writer(derp.Split('x').GetOrDefault(1) ?? ".");
答案 4 :(得分:1)
问题在于derp.Split('x')[1]
。
您无法检查[1]元素是否为空,因为它不存在。想象一下情况:
我给你一个桶,把'fooooo'放进去。
然后我问你,"Is the second bucket empty?"
。
你不能说"yes"
,你不能说"no"
。桶只是不存在,所以你会说"ArrayIndexOutOfBoundsException"
- 没有第二个桶,所以我无法检查它是否为空;)
答案 5 :(得分:0)
如果不是特殊情况,请不要使用例外,如果可以的话。
在这个具体案例中,你可以避免使用异常并只使用简单的边界控制,就像(只是一个例子):
var splitted = derp.Split('x');
if(splitted.Length > 1) {
Writer(derp.Split('x')[0] ?? ".");
Writer(derp.Split('x')[1] ?? ".");
}
答案 6 :(得分:0)
您应该使用if
声明:
var result = derp.Split('x');
if (result.Length > 0)
Writer(result[0]);
else
//...
答案 7 :(得分:0)
迭代Split
var splitOutput = derp.Split('x');
foreach (var s in splitOutput)
Writer(s);
}
答案 8 :(得分:0)
分而治之。
如果您希望该值存在:
static void Main(string[] args)
{
string derp = "foooooo";
var parts = derp.Split('x');
if (parts.Length != 2)
throw new InvalidOperationException("Expected string to have to dot X delimited values. Actual string: " + derp);
Writer(derp.Split('x')[0] ?? ".");
Writer(derp.Split('x')[1] ?? ".");
}
如果您希望缺少这些值:
static void Main(string[] args)
{
string derp = "foooooo";
var parts = derp.Split('x');
if (parts.Length > 0)
Writer(parts[0]);
else
Writer(".");
if (parts.Length > 1)
Writer(parts[1]);
else
Writer(".");
}