如何 return 来自方法的 switch 语句的不确定类型的值
How to return a value of indeterminate type from a switch statement from a method
我有以下 switch 语句:
switch (SomeType)
{
case SomeType.A:
var data = (Type_1)SomeType.Data;
case SomeType.B:
var data = (Type_2)SomeType.Data;
case SomeType.C:
var data = (Type_3) SomeType.Data;
case SomeType.D:
var data = (Type_4) SomeType.Data;
case SomeType.E:
var data = (Type_5) SomeType.Data;
case SomeType.F:
var data = (Type_6) SomeType.Data;
}
我有两个问题:
一个是 switch 语句似乎将整个事情视为一个范围,因此我不能多次设置 var data
,我想我可以克服这个问题,因为这需要包装在一个方法中return 是值,所以我可以做类似 return (Type_6) SomeType.Data;
的事情。
第二个问题是如何将其包装在 return 方法中?据我所知,在 C# 中,该方法必须显式定义 return 类型。有什么想法吗?
动态
您可以使用 dynamic 作为 return 类型:
public dynamic GetData()
{
dynamic data;
switch (SomeType)
{
case SomeType.A:
data = (Type_1)SomeType.Data;
case SomeType.B:
data = (Type_2)SomeType.Data;
case SomeType.C:
data = (Type_3) SomeType.Data;
case SomeType.D:
data = (Type_4) SomeType.Data;
case SomeType.E:
data = (Type_5) SomeType.Data;
case SomeType.F:
data = (Type_6) SomeType.Data;
default: throw new NotSupportedException();
}
return data;
}
只需添加一些 break
语句,否则将无法编译。
但动态是 highly contagious - 如果您在一种方法中使用它,它可能会传播到所有使用原始方法的方法。
重构架构
虽然动态是一个快速解决方案,但它并不是最好的解决方案,因为评论员已经指出了这一点。理想情况下,您应该努力尽可能多地保留类型信息 - 它可以简化开发并减少出错的可能性。
您可以为所有可能的数据对象使用一些基础 class 或接口:
public interface IData
{
// Common properties and methods
}
public IData GetData()
{
return SomeData.Data;
}
但这可能需要对您的体系结构进行实质性的重新考虑,如果不同的 Data
类型差异太大,这可能会也可能不会。
访客模式
如果是这种情况,那么您可以查看 Visitor Pattern 处理必须以非常不同的方式处理数据的情况。它仍然需要与 return 类型相同的基本接口,但现在它看起来像:
public interface IData
{
void Accept(IDataVisitor visitor);
}
public interface IDataVisitor
{
void Visit(DataA data);
void Visit(DataB data);
void Visit(DataC data);
}
public class DataA : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class DataB : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class DataC : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class ConsoleVisitor : IDataVisitor
{
public void Visit(DataA data)
{
Console.WriteLine("A" + data);
}
public void Visit(DataB data)
{
Console.WriteLine("B" + data);
}
public void Visit(DataC data)
{
Console.WriteLine("C" + (data);
}
}
我有以下 switch 语句:
switch (SomeType)
{
case SomeType.A:
var data = (Type_1)SomeType.Data;
case SomeType.B:
var data = (Type_2)SomeType.Data;
case SomeType.C:
var data = (Type_3) SomeType.Data;
case SomeType.D:
var data = (Type_4) SomeType.Data;
case SomeType.E:
var data = (Type_5) SomeType.Data;
case SomeType.F:
var data = (Type_6) SomeType.Data;
}
我有两个问题:
一个是 switch 语句似乎将整个事情视为一个范围,因此我不能多次设置 var data
,我想我可以克服这个问题,因为这需要包装在一个方法中return 是值,所以我可以做类似 return (Type_6) SomeType.Data;
的事情。
第二个问题是如何将其包装在 return 方法中?据我所知,在 C# 中,该方法必须显式定义 return 类型。有什么想法吗?
动态
您可以使用 dynamic 作为 return 类型:
public dynamic GetData()
{
dynamic data;
switch (SomeType)
{
case SomeType.A:
data = (Type_1)SomeType.Data;
case SomeType.B:
data = (Type_2)SomeType.Data;
case SomeType.C:
data = (Type_3) SomeType.Data;
case SomeType.D:
data = (Type_4) SomeType.Data;
case SomeType.E:
data = (Type_5) SomeType.Data;
case SomeType.F:
data = (Type_6) SomeType.Data;
default: throw new NotSupportedException();
}
return data;
}
只需添加一些 break
语句,否则将无法编译。
但动态是 highly contagious - 如果您在一种方法中使用它,它可能会传播到所有使用原始方法的方法。
重构架构
虽然动态是一个快速解决方案,但它并不是最好的解决方案,因为评论员已经指出了这一点。理想情况下,您应该努力尽可能多地保留类型信息 - 它可以简化开发并减少出错的可能性。
您可以为所有可能的数据对象使用一些基础 class 或接口:
public interface IData
{
// Common properties and methods
}
public IData GetData()
{
return SomeData.Data;
}
但这可能需要对您的体系结构进行实质性的重新考虑,如果不同的 Data
类型差异太大,这可能会也可能不会。
访客模式
如果是这种情况,那么您可以查看 Visitor Pattern 处理必须以非常不同的方式处理数据的情况。它仍然需要与 return 类型相同的基本接口,但现在它看起来像:
public interface IData
{
void Accept(IDataVisitor visitor);
}
public interface IDataVisitor
{
void Visit(DataA data);
void Visit(DataB data);
void Visit(DataC data);
}
public class DataA : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class DataB : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class DataC : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class ConsoleVisitor : IDataVisitor
{
public void Visit(DataA data)
{
Console.WriteLine("A" + data);
}
public void Visit(DataB data)
{
Console.WriteLine("B" + data);
}
public void Visit(DataC data)
{
Console.WriteLine("C" + (data);
}
}