我的一位同事想出了这个,我想知道别人怎么想?就个人而言,我觉得它很有趣,但想知道它是否太大了?代码示例如下.底部的扩展方法.
请一般的想法.可以添加的其他扩展方法?
var ddl = Page.FindControl("LocationDropDownList") as DropDownList;
ddl.Visible = true;
ddl.SelectedValue = "123";
if(isAdmin)
ddl .SelectedValue = "111";
Run Code Online (Sandbox Code Playgroud)
变为:
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.With(d => d.Visible = true)
.With(d => d.SelectedValue = "123")
.WithIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
Run Code Online (Sandbox Code Playgroud)
要么:
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.With(d =>
{
d.Visible = true;
d.SelectedValue = "123";
})
.WithIf(isAdmin, d => d.SelectedValue = "111");
Run Code Online (Sandbox Code Playgroud)
扩展方法:
public static TResult CastAs<TResult>(this object obj) where TResult : class
{
return obj as TResult;
}
public static T With<T>(this T t, Action<T> action)
{
if (action == null)
throw new ArgumentNullException("action");
action(t);
return t;
}
public static T WithIf<T>(this T t, bool condition, Action<T> action)
{
if (action == null)
throw new ArgumentNullException("action");
if (condition)
action(t);
return t;
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 60
我编写清晰代码的经验法则是:将所有副作用放在语句中; 非语句表达式应该没有副作用.
您的第一个程序版本明确遵循此规则.第二个版本显然违反了它.
另外一个想法:如果我要阅读代码,就像你显示的代码一样,我自然会认为代码的目的是构建一个代表那些操作的延迟评估结构 - 这正是查询理解的原因所在. C#3就是以这种方式构建的.查询表达式的结果是表示查询的延迟应用程序的对象.
如果您的目的是捕捉"在我选择的后期以延迟的方式执行这些副作用"的概念,那么这是一种明智的方法.基本上你正在建立的是一个副作用的monad.如果您的意图仅仅是为急切执行的代码提供不同的语法,那么这只会令人困惑,冗长和不必要.
mqp*_*mqp 49
除了让读者感到困惑之外,我认为没有任何好处.关于我的回答者,我想知道哪个星球更具可读性.据我所知,第一个版本具有或多或少的完美可读性,而这是相当可读的,但让读者想知道是否有一些奇怪的魔法发生在内部With
和WithIf
.
与第一个版本相比,它更长,更难打字,更不明显,性能更低.
再投票"没用".With
除了使用方法包装序列语句之外,扩展方法不会执行任何操作.C#已经有一个用于测序语句的内置函数,它被称为;
.
类似地,WithIf
包装if语句而不对控制流进行任何修改.从我的角度来看,你只是邀请自己采用以下方法:
public static T For<T>(
this T t, int start, Func<int, bool> cond, Action<T, int> f)
{
for(int i = start; cond(i); i++)
{
f(t, i);
}
return t;
}
Run Code Online (Sandbox Code Playgroud)
原件更具可读性.
最简单的API更改是使FindControl()返回的对象成为一个Builder-esque的东西(其中所有set方法都返回'this'):
Page.FindControl("LocationDropDownList")
.setVisible(true)
.setSelectedValue(isAdmin ? "111" : "123");
Run Code Online (Sandbox Code Playgroud)