我相信这个解决方案是最直接的解决方案,你应该使用它:
switch(a) {
case 1: return "lalala";
case 2: return "blabla";
case 3: return "lololo";
default: return "default";
}
但是,既然你问了一个return
,你可以使用这个小流利类:
public class Switch<TElement, TResult> {
TElement _element;
TElement _currentCase;
IDictionary<TElement, TResult> _map = new Dictionary<TElement, TResult>();
public Switch(TElement element) { _element = element; }
public Switch<TElement, TResult> Case(TElement element) {
_currentCase = element;
return this;
}
public Switch<TElement, TResult> Then(TResult result) {
_map.Add(_currentCase, result);
return this;
}
public TResult Default(TResult defaultResult) {
TResult result;
if (_map.TryGetValue(_element, out result)) {
return result;
}
return defaultResult;
}
}
像这样创建代码:
return new Switch<int, string>(a)
.Case(1).Then("lalala")
.Case(2).Then("blabla")
.Case(3).Then("lololo")
.Default("default");
不幸的是,类型参数不能由编译器推断,而且感觉有点笨拙。 Default
将触发对“开关”的评估,并且必须是链中最后的方法调用。请注意,您始终需要一个默认值,因为您已将switch
转换为表达式。
UPDATE:你能解决这个类型推断问题和驱动用户做正确的事与此代码:
public static class Switch {
public static SwitchBuilder<TElement>.CaseBuilder On<TElement>(TElement element) {
return new SwitchBuilder<TElement>(element).Start();
}
public class SwitchBuilder<TElement> {
TElement _element;
TElement _firstCase;
internal SwitchBuilder(TElement element) { _element = element; }
internal CaseBuilder Start() {
return new CaseBuilder() { Switch = this };
}
private ThenBuilder Case(TElement element) {
_firstCase = element;
return new ThenBuilder() { Switch = this };
}
private SwitchBuilder<TElement, TResult>.CaseBuilder Then<TResult>(TResult result) {
return new SwitchBuilder<TElement, TResult>(
_element,
_firstCase,
result).Start();
}
public class CaseBuilder {
internal SwitchBuilder<TElement> Switch { get; set; }
public ThenBuilder Case(TElement element) {
return Switch.Case(element);
}
}
public class ThenBuilder {
internal SwitchBuilder<TElement> Switch { get; set; }
public SwitchBuilder<TElement, TResult>.CaseBuilder Then<TResult>(TResult result) {
return Switch.Then(result);
}
}
}
public class SwitchBuilder<TElement, TResult> {
TElement _element;
TElement _currentCase;
IDictionary<TElement, TResult> _map = new Dictionary<TElement, TResult>();
internal SwitchBuilder(TElement element, TElement firstCase, TResult firstResult) {
_element = element;
_map.Add(firstCase, firstResult);
}
internal CaseBuilder Start() {
return new CaseBuilder() { Switch = this };
}
private ThenBuilder Case(TElement element) {
_currentCase = element;
return new ThenBuilder() { Switch = this };
}
private CaseBuilder Then(TResult result) {
_map.Add(_currentCase, result);
return new CaseBuilder() { Switch = this };
}
private TResult Default(TResult defaultResult) {
TResult result;
if (_map.TryGetValue(_element, out result)) {
return result;
}
return defaultResult;
}
public class CaseBuilder {
internal SwitchBuilder<TElement, TResult> Switch { get; set; }
public ThenBuilder Case(TElement element) {
return Switch.Case(element);
}
public TResult Default(TResult defaultResult) {
return Switch.Default(defaultResult);
}
}
public class ThenBuilder {
internal SwitchBuilder<TElement, TResult> Switch { get; set; }
public CaseBuilder Then(TResult result) {
return Switch.Then(result);
}
}
}
}
结果是这样的漂亮,类型安全,流畅的界面;其中,在每一步你只有方法正确的选择调用(如Case
后Then
):
return Switch.On(a)
.Case(1).Then("lalala")
.Case(2).Then("blabla")
.Case(3).Then("lololo")
.Default("default");
AFAIK,切换不会返回值,因此您的使用是不可能的。 为什么你想这样做? – SWeko 2010-07-26 11:05:38