我有一个实例,我是C#delegates,Func,Expression和action的新手。我想传递一个参数作为一个表达式,它将检查几个条件,然后它将返回或执行基于某些条件,提供类似这样的
var result = Uow.GroupLicense.Set
.Join(Uow.UserGroup.Set, x => x.GroupGuid, y => y.GroupGuid, (GL, G) => new { G, GL })
.Join(Uow.Users.Set, x => x.G.UserGuid, y => y.UserGuid, (UG, U) => new { UG, U })
.SingleOrDefault(x => x.U.UserID == Username);
if (result != null && result.UG.GL.IsActive && result.U.IsEnabled && !result.U.IsLocked)
{
SessionStorage.LoginAttempts = UpdateLoginAttempts(Username, true);
SessionStorage.SessionID = HttpContext.Current.Session.SessionID;
SessionStorage.LoginAttempts = 0;
SessionStorage.UserName = Username;
SessionStorage.ABBUserName = Username;
}
else if (!result.UG.GL.IsActive)
{
result.U.IsEnabled = false;
result.U.IsLocked = true;
Uow.Users.Update(result.U);
Uow.Commit();
ErrorMessage = "User License Expired";
}
else if (result.U.IsLocked)
{
ErrorMessage = "User is locked";
}
else if (!result.U.IsEnabled)
{
ErrorMessage = "User is disabled by administrator";
}
else
{
ErrorMessage = "User doesnt exist ";
}
现在这是我的原始代码。我想根据两个类项条件将其转换为决策树。像这样的东西
if this -> Boolean result = EnsureLicense((x, y) => x.IsEnabled && y.IsActive);
then do Action1
if This -> Boolean result = EnsureLicense((x, y) => !x.IsEnabled && y.IsActive);
then do Action2
if This - > Boolean result = EnsureLicense((x, y) => !x.IsEnabled && y.IsLocked);
then do Action3.
我不想把它切换成类似if else结构代码的多个if else和else if结构代码。如何处理这种策略,因为我无法进入切换案例。
我想用Actions和Expression以及Func委托来做。我想学习如何继续这种策略。
请指导我
答案 0 :(得分:1)
这是带有动作和Func委托的解决方案,它们不使用if ... else结构。实际上这是一种Chain of Responsibility:
public class LicenseHandler
{
private readonly Func<GroupLicense, User, bool> predicate;
private readonly Action action;
private LicenseHandler nextHandler;
public LicenseHandler(Func<GroupLicense,User, bool> predicate, Action action)
{
this.action = action;
this.predicate = predicate;
}
public LicenseHandler SetNext(LicenseHandler handler)
{
nextHandler = handler;
return this;
}
public void Handle(GroupLicense license, User user)
{
if (predicate(license, user))
{
action();
return;
}
if (nextHandler != null)
nextHandler.Handle(license, user);
}
}
创建处理程序并将它们链接起来:
var handler1 = new LicenseHandler((l, u) => l.IsEnabled && u.IsActive, Action1);
var handler2 = new LicenseHandler((l, u) => !l.IsEnabled && u.IsActive, Action2);
var handler3 = new LicenseHandler((l, u) => !l.IsEnabled && u.IsLocked, Action3);
handler1.SetNext(handler2.SetNext(handler3));
处理看起来像
handler1.Handle(licence, user);
支持基于代理的代码而不是简单的if-else的人会接受我最深切的同情。
更新:如果你想要漂亮的流畅API,那么你可以创建构建器类,它将创建处理程序链:
public class LicenseHandlerBuilder
{
private LicenseHandler root;
private LicenseHandler current;
private LicenseHandlerBuilder() { }
public static LicenseHandlerBuilder CreateHandler(
Func<GroupLicense, User, bool> predicate, Action action)
{
var builder = new LicenseHandlerBuilder();
builder.root = new LicenseHandler(predicate, action);
builder.current = builder.root;
return builder;
}
public LicenseHandlerBuilder WithNext(
Func<GroupLicense, User, bool> predicate, Action action)
{
var next = new LicenseHandler(predicate, action);
current.SetNext(next);
current = next;
return this;
}
public LicenseHandler Build()
{
return root;
}
}
用法:
var handler = LicenseHandlerBuilder
.CreateHandler((l, u) => l.IsEnabled && u.IsActive, Action1)
.WithNext((l, u) => !l.IsEnabled && u.IsActive, Action2)
.WithNext((l, u) => !l.IsEnabled && u.IsLocked, Action3)
.Build();