Ann*_*ang 7 .net c# mapping enums
我正在网上预订网站(航空公司)工作,我想根据一些设置验证用户/客户选择的路线是否有效.现有的代码使用了大量的枚举,我发现自己做了很多if/if else/else来将特定的枚举映射到我想要发生的特定动作.What I want to do is to write a enum-specific method that would do the mapping for me. Is there any standard way to do this?
这是应用程序代码的简化版本,使用来自真实应用程序的相同类名/枚举值等:
// real app has 9 members, shortened for simplicity's sake
public enum RegionType
{
Station,
Country,
All
}
public enum Directionality
{
Between,
From,
To
}
// simplified version
public class Flight
{
public RegionType RegionType { get; set; }
public RegionType TravelRegionType { get; set; }
public string RegionCode { get; set; }
public string TravelRegionCode { get; set; }
public string RegionCountryCode { get; set; }
public string TravelRegionCountryCode { get; set; }
public Directionality Directionality { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以下是一些示例用法:
// valid flight
Flight flight = new Flight()
{
RegionCode = "NY",
CountryCode = "JP",
RegionType = RegionType.Station,
TravelRegionType = RegionType.Country,
Directionality = Directionality.Between
};
// these are the station code/country code that user selected
// needs to be validated against the Flight object above
var userSelectedRoutes = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("NY", "JP"),
new KeyValuePair<string, string>("NY", "AU"),
new KeyValuePair<string, string>("JP", "NY")
};
Run Code Online (Sandbox Code Playgroud)
我写的一些代码验证减少了嵌套if/else if/else枚举匹配:
private bool IsRouteValid(Directionality direction, string origin,
string destination, string departure, string arrival)
{
// both departure station and arrival station
if (direction == Directionality.Between)
{
return (origin.Equals(departure, StringComparison.OrdinalIgnoreCase)
&& destination.Equals(arrival, StringComparison.OrdinalIgnoreCase)
|| origin.Equals(arrival, StringComparison.OrdinalIgnoreCase)
&& destination.Equals(departure, StringComparison.OrdinalIgnoreCase));
}
else if (direction == Directionality.From)
{
return (origin.Equals(departure,
StringComparison.OrdinalIgnoreCase));
}
else if (direction == Directionality.To)
{
return (destination.Equals(arrival,
StringComparison.OrdinalIgnoreCase));
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
这是我想要改变的混乱代码:
if (flight.RegionType == RegionType.Station
&& flight.TravelRegionType == RegionType.Country)
{
return userSelectedRoutes.Any(route =>
IsRouteValid(flight.Directionality, route.Key, route.Value,
flight.RegionCode, flight.TravelRegionCode));
}
else if (flight.RegionType == RegionType.Country
&& flight.TravelRegionType == RegionType.Station)
{
return userSelectedRoutes.Any(route =>
IsRouteValid(flight.Directionality, route.Key, route.Value,
flight.CountryCode, flight.RegionCode));
}
else if (flight.RegionType == RegionType.Station
&& flight.TravelRegionType == RegionType.Station)
{
return userSelectedRoutes.Any(route =>
IsRouteValid(flight.Directionality, route.Key, route.Value,
flight.RegionCode, flight.TravelRegionCode));
}
else if (flight.RegionType == RegionType.Station
&& flight.TravelRegionType == RegionType.All)
{
return userSelectedRoutes.Any(route =>
IsRouteValid(flight.Directionality, route.Key, route.Value,
flight.RegionCode, route.Value));
}
else if (flight.RegionType == RegionType.All
&& flight.TravelRegionType == RegionType.Station)
{
return userSelectedRoutes.Any(route =>
IsRouteValid(flight.Directionality, route.Key, route.Value,
route.Key, flight.TravelRegionCode));
}
else if (flight.RegionType == RegionType.All
&& flight.TravelRegionType == RegionType.All)
{
return true;
}
else
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
传说:
RegionCode=出发站/始发地
TravelRegionCode=到达站/目的地
Between=路线必须仅来自给定的出发站和到达站,反之亦然(前NY-JP或JP-NY)
From=从特定站到任何路线(前AU- 全部)
To=到特定电台的任何路线(来自所有 -AU)
如果您注意到,上述.Any所有条件中的所有条件都是相同的,只是略有变化.如果可能,我想减少代码冗余.我用过,KeyValuePair所以我有一个单一数据类型的出发站和到站.
关于如何让这些代码变得更加混乱/美观的任何想法?我知道我也硬编码IsRouteValid()但我100%肯定Directionality只能有3种可能的组合.RegionType另一方面,可以有几个组合,如站 - 站,站 - 国家,国家 - 站,国家 - 国家等.
预期产出:
有效/真对于第一路线(NY-JP)
无效/ False的第二路线(NY-AU)
有效/真对于第三路线(JP-NY)[自DirectionalityIS Between]
感谢您阅读这个非常长的查询,并提前感谢您的反馈和建议.
类似帖子:
Mat*_*asG 20
处理这种枚举动作映射的一种方法是使用字典.这是一个例子:
public enum MyEnum
{
EnumValue1,
EnumValue2,
EnumValue3
}
private IDictionary<MyEnum, Action> Mapping = new Dictionary<MyEnum, Action>
{
{ MyEnum.EnumValue1, () => { /* Action 1 */ } },
{ MyEnum.EnumValue2, () => { /* Action 2 */ } },
{ MyEnum.EnumValue3, () => { /* Action 3 */ } }
};
public void HandleEnumValue(MyEnum enumValue)
{
if (Mapping.ContainsKey(enumValue))
{
Mapping[enumValue]();
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您也可以使用Func而不是Action处理参数.
编辑:
由于您不仅使用一个枚举而是使用枚举对,因此您必须调整上面的示例,以便可以处理一种Tuple或另一种方式来聚合枚举值.