寻找此开关盒或任何其他解决方案的替代方法
looking alternative way for this switch case or any other solution
我正在执行数据库更新操作,并根据类型更新一些字段,这些字段被传递给带有 switch case 语句的内部方法,目前它有 4 个 case 语句并且它会变大..
我正在寻找一种方法将此 switch case 转换为具有键值对的字典或任何类型的机制以在方法内部实现。
这是主要方法
public async Task<MutationResponse> SetRequestStage(string requestStage, Guid requestId, MasterSectionEnum masterSectionEnum)
{
var request = _dbContext.Requests.SingleOrDefault(r => r.Id == requestId);
var rs = _dbContext.RequestStages.SingleOrDefault(rs => rs.Name == requestStage);
if (rs != null)
{
request.RequestStage = rs;
if (rs.Name == "Approved")
{
switch (masterSectionEnum)
{
case MasterSectionEnum.LOCALCODE:
await UpdateRevision<LocalCode>(request.DataId).ConfigureAwait(false);
break;
case MasterSectionEnum.NATIONALCODE:
await UpdateRevision<NationalCode>(request.DataId).ConfigureAwait(false);
break;
case MasterSectionEnum.GUIDELINES:
await UpdateRevision<Guideline>(request.DataId).ConfigureAwait(false);
break;
case MasterSectionEnum.LIBRARYA621:
await UpdateRevision<LibraryA621>(request.DataId).ConfigureAwait(false);
break;
case .....
case .....
default:
throw new ArgumentException($"SetRequestStage Error: invalid MasterSection {masterSectionEnum.ToString()}");
}
}
}
_dbContext.SaveChanges();
return new MutationResponse();
}
这将是枚举
public enum MasterSectionEnum
{
LOCALCODE,
NATIONALCODE,
GUIDELINES,
SPACETYPE,
LIBRARYA621
// this will grow bigger
}
这将是我从上述方法调用的内部方法
private async Task UpdateRevision<T>(Guid id) where T : class, IAEIMaster, IRevisionData
{
var dbSet = this._dbContext.Set<T>();
var code = dbSet.SingleOrDefault(c => c.Id == id);
......
......
code.Revision = revision;
code.IsApproved = true;
}
任何人都可以建议如何将此 switch case 转换为具有键值对或类型的替代类型,我将非常感激。
非常感谢
更新:我正在寻找下面的方法,我正在使用带 EF 核心的点网核心
var types = new Dictionary<string, string>();
foreach(var item in types)
{
if(item.Key == "enum value")
{
await UpdateRevision<item.value>(request.DataId).ConfigureAwait(false);
}
}
你可以试试这个:
public enum MasterSectionEnum
{
LOCALCODE,
NATIONALCODE
}
public sealed class LocalCode { }
public sealed class NationalCode { }
public sealed class Program
{
private static readonly Dictionary<MasterSectionEnum, Func<Guid, Task>> Dictionary
= new Dictionary<MasterSectionEnum, Func<Guid, Task>>();
static Program()
{
Dictionary[MasterSectionEnum.LOCALCODE] = UpdateRevision<LocalCode>;
Dictionary[MasterSectionEnum.NATIONALCODE] = UpdateRevision<NationalCode>;
}
public static async Task SetRequestStage(MasterSectionEnum masterSectionEnum)
{
await Dictionary[masterSectionEnum].Invoke(Guid.NewGuid());
}
private static Task UpdateRevision<T>(Guid id) where T : class
{
Console.WriteLine(typeof(T));
return Task.CompletedTask;
}
public static async Task Main()
{
await SetRequestStage(MasterSectionEnum.LOCALCODE);
await SetRequestStage(MasterSectionEnum.NATIONALCODE);
Console.ReadKey();
}
}
结果:
LocalCode
NationalCode
不要传入参数 MasterSectionEnum,而是更改您的方法以接受类型参数。然后只需在 UpdateRevision
.
的单个调用中使用该泛型类型
public async Task<MutationResponse> SetRequestStage<SectionType>(
string requestStage,
Guid requestId
) {
...
await UpdateRevision<SectionType>(request.DataId).ConfigureAwait(false);
....
}
如果 SectionType
的所有有效类型共享一个接口或派生自同一个 class,那么您可以更进一步,向 SectionType
添加约束,避免在运行时处理错误类型。
编辑:
所以 SetRequestStage
不能是通用的吧?好吧,使它成为通用的倾向源于它依赖于通用的 UpdateRevision
这一事实。这又取决于DbContext.Set()
。而且您正在使用它的通用版本。但好消息是它似乎有一个 non-generic version 接受类型变量作为参数。所以:
async Task UpdateRevision<T>(
Guid id,
Type t
) where T : class, IAEIMaster, IRevisionData {
var dbSet = this._dbContext.Set(t);
...
}
然后:
public async Task<MutationResponse> SetRequestStage(
string requestStage,
Guid requestId,
Type SectionType
) {
...
await UpdateRevision(request.DataId, SectionType).ConfigureAwait(false);
....
}
我不知道你的UI长什么样。但是,一般来说:
var dic = new Dictionary<MasterSectionEnum, Type> {
{ MasterSectionEnum.LOCALCODE, typeof(LocalCode) },
{ MasterSectionEnum.NATIONALCODE, typeof(NationalCode) },
...
};
public async someUiRelatedMethod(
string reqStage,
Guid reqId,
MasterSectionEnum sectionType
) {
await SetRequestStage(reqStage, reqId, dic[sectionType]);
}
抱歉,如果后者的语法不太正确。但是你明白了。
我正在执行数据库更新操作,并根据类型更新一些字段,这些字段被传递给带有 switch case 语句的内部方法,目前它有 4 个 case 语句并且它会变大..
我正在寻找一种方法将此 switch case 转换为具有键值对的字典或任何类型的机制以在方法内部实现。
这是主要方法
public async Task<MutationResponse> SetRequestStage(string requestStage, Guid requestId, MasterSectionEnum masterSectionEnum)
{
var request = _dbContext.Requests.SingleOrDefault(r => r.Id == requestId);
var rs = _dbContext.RequestStages.SingleOrDefault(rs => rs.Name == requestStage);
if (rs != null)
{
request.RequestStage = rs;
if (rs.Name == "Approved")
{
switch (masterSectionEnum)
{
case MasterSectionEnum.LOCALCODE:
await UpdateRevision<LocalCode>(request.DataId).ConfigureAwait(false);
break;
case MasterSectionEnum.NATIONALCODE:
await UpdateRevision<NationalCode>(request.DataId).ConfigureAwait(false);
break;
case MasterSectionEnum.GUIDELINES:
await UpdateRevision<Guideline>(request.DataId).ConfigureAwait(false);
break;
case MasterSectionEnum.LIBRARYA621:
await UpdateRevision<LibraryA621>(request.DataId).ConfigureAwait(false);
break;
case .....
case .....
default:
throw new ArgumentException($"SetRequestStage Error: invalid MasterSection {masterSectionEnum.ToString()}");
}
}
}
_dbContext.SaveChanges();
return new MutationResponse();
}
这将是枚举
public enum MasterSectionEnum
{
LOCALCODE,
NATIONALCODE,
GUIDELINES,
SPACETYPE,
LIBRARYA621
// this will grow bigger
}
这将是我从上述方法调用的内部方法
private async Task UpdateRevision<T>(Guid id) where T : class, IAEIMaster, IRevisionData
{
var dbSet = this._dbContext.Set<T>();
var code = dbSet.SingleOrDefault(c => c.Id == id);
......
......
code.Revision = revision;
code.IsApproved = true;
}
任何人都可以建议如何将此 switch case 转换为具有键值对或类型的替代类型,我将非常感激。
非常感谢
更新:我正在寻找下面的方法,我正在使用带 EF 核心的点网核心
var types = new Dictionary<string, string>();
foreach(var item in types)
{
if(item.Key == "enum value")
{
await UpdateRevision<item.value>(request.DataId).ConfigureAwait(false);
}
}
你可以试试这个:
public enum MasterSectionEnum
{
LOCALCODE,
NATIONALCODE
}
public sealed class LocalCode { }
public sealed class NationalCode { }
public sealed class Program
{
private static readonly Dictionary<MasterSectionEnum, Func<Guid, Task>> Dictionary
= new Dictionary<MasterSectionEnum, Func<Guid, Task>>();
static Program()
{
Dictionary[MasterSectionEnum.LOCALCODE] = UpdateRevision<LocalCode>;
Dictionary[MasterSectionEnum.NATIONALCODE] = UpdateRevision<NationalCode>;
}
public static async Task SetRequestStage(MasterSectionEnum masterSectionEnum)
{
await Dictionary[masterSectionEnum].Invoke(Guid.NewGuid());
}
private static Task UpdateRevision<T>(Guid id) where T : class
{
Console.WriteLine(typeof(T));
return Task.CompletedTask;
}
public static async Task Main()
{
await SetRequestStage(MasterSectionEnum.LOCALCODE);
await SetRequestStage(MasterSectionEnum.NATIONALCODE);
Console.ReadKey();
}
}
结果:
LocalCode
NationalCode
不要传入参数 MasterSectionEnum,而是更改您的方法以接受类型参数。然后只需在 UpdateRevision
.
public async Task<MutationResponse> SetRequestStage<SectionType>(
string requestStage,
Guid requestId
) {
...
await UpdateRevision<SectionType>(request.DataId).ConfigureAwait(false);
....
}
如果 SectionType
的所有有效类型共享一个接口或派生自同一个 class,那么您可以更进一步,向 SectionType
添加约束,避免在运行时处理错误类型。
编辑:
所以 SetRequestStage
不能是通用的吧?好吧,使它成为通用的倾向源于它依赖于通用的 UpdateRevision
这一事实。这又取决于DbContext.Set()
。而且您正在使用它的通用版本。但好消息是它似乎有一个 non-generic version 接受类型变量作为参数。所以:
async Task UpdateRevision<T>(
Guid id,
Type t
) where T : class, IAEIMaster, IRevisionData {
var dbSet = this._dbContext.Set(t);
...
}
然后:
public async Task<MutationResponse> SetRequestStage(
string requestStage,
Guid requestId,
Type SectionType
) {
...
await UpdateRevision(request.DataId, SectionType).ConfigureAwait(false);
....
}
我不知道你的UI长什么样。但是,一般来说:
var dic = new Dictionary<MasterSectionEnum, Type> {
{ MasterSectionEnum.LOCALCODE, typeof(LocalCode) },
{ MasterSectionEnum.NATIONALCODE, typeof(NationalCode) },
...
};
public async someUiRelatedMethod(
string reqStage,
Guid reqId,
MasterSectionEnum sectionType
) {
await SetRequestStage(reqStage, reqId, dic[sectionType]);
}
抱歉,如果后者的语法不太正确。但是你明白了。