更流畅的C#/.NET
我的一个同事想出了这个主意,我想知道其他人怎么想?就我个人而言,我觉得这很有趣,但不知道这是否是一个太大的偏离?下面是代码示例。底部的扩展方法 请概括一下。可以添加的其他扩展方法更流畅的C#/.NET,c#,C#,我的一个同事想出了这个主意,我想知道其他人怎么想?就我个人而言,我觉得这很有趣,但不知道这是否是一个太大的偏离?下面是代码示例。底部的扩展方法 请概括一下。可以添加的其他扩展方法 var ddl = Page.FindControl("LocationDropDownList") as DropDownList; ddl.Visible = true; ddl.SelectedValue = "123"; if(isAdmin) ddl .SelectedValue = "111"
var ddl = Page.FindControl("LocationDropDownList") as DropDownList;
ddl.Visible = true;
ddl.SelectedValue = "123";
if(isAdmin)
ddl .SelectedValue = "111";
变成:
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")));
Page.FindControl(“LocationDropDownList”)
卡斯塔斯先生()
.With(d=>d.Visible=true)
.With(d=>d.SelectedValue=“123”)
.WithIf(isAdmin,d=>d.Items.Add(新列表项(“Admin”,“1”)));
或:
Page.FindControl(“LocationDropDownList”)
卡斯塔斯先生()
.与(d=>
{
d、 可见=真实;
d、 SelectedValue=“123”;
})
.WithIf(isAdmin,d=>d.SelectedValue=“111”);
扩展方法:
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;
}
公共静态TResult CastAs(此对象obj),其中TResult:class
{
将obj返回为TResult;
}
公共静态T与(此T,动作)
{
if(action==null)
抛出新的异常(“操作”);
行动(t);
返回t;
}
带IF的公共静态T(此T T、布尔条件、动作)
{
if(action==null)
抛出新的异常(“操作”);
如果(条件)
行动(t);
返回t;
}
除了让读者感到困惑之外,我认为这没有什么好处。关于我的回答者同伴,我想知道这在哪个星球上更具可读性。据我所知,第一个版本或多或少具有完美的可读性,而这是相当可读的,但让读者怀疑在With
和WithIf
中是否发生了一些奇怪的魔法
与第一个版本相比,它更长,更难输入,更不明显,性能更低。如果我看到过的话,这是一些扩展方法滥用 我想我看不出新版本给你带来了什么。原文很清楚,没有那么冗长。我猜它也会更快。除非有明显的好处,否则我会避免使用(滥用?)这样的语言功能。它们只是不同的编码风格,你说“偏离太大”是什么意思?离开什么?你习惯了什么?只有你能决定。我会说VB的
With
块对代码可读性弊大于利,我不会尝试在C#中复制这种行为,但这只是我的偏好
我几乎总是在FindControl
中使用它(是的,强键入到RepeaterItem
,它不一定是,但这是我唯一使用它的原因):
公共静态T FindControl(此RepeaterItem项,字符串id)
{
将item.FindControl(id)返回为T;
}
并像这样调用它:
Literal myLiteral = e.Item.FindControl<Literal>("myLiteral");
Literal myLiteral=e.Item.FindControl(“myLiteral”);
我的2美分:看起来不错,我唯一的评论是“With”在实际设置属性时有点像“Where”或“have”。我建议使用“Do”、“Execute”或“Set”之类的方法名称,但这可能只是我奇怪的世界观
那么:
Page.WithControl<DropDownList>("LocationDropDownList")
.Do(d => d.Visible = true)
.Do(d => d.SelectedValue = "123")
.DoIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
Page.with控件(“LocationDropDownList”)
.Do(d=>d.Visible=true)
.Do(d=>d.SelectedValue=“123”)
.DoIf(isAdmin,d=>d.Items.Add(新列表项(“Admin”,“1”)));
我要说的是,坚持使用没有扩展方法或lamba表达式的第一个版本。这些都是相对较新的概念,因此没有多少开发人员能够处理这些概念,而不是将其用于数据库中的数据检索/操作。如果您使用它们,您可能会对维护成本产生影响。说“如果你觉得这是希腊语,就把它读出来”很好;但在现实生活中,这可能是最好的方法 我对第一个版本比较满意。阅读和理解所需的时间更少。我同意,如果您熟悉扩展方法,并且也熟悉with方法,那么扩展方法也可以,但是在这种情况下,它有什么好处呢 扩展的使用很有趣,我很欣赏它的优点。我不确定我是否会使用它,但如果您的团队喜欢它,那么请务必使用它。再投一票赞成“无用”。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;
}
publicstatict(
这T T,int start,funct cond,Action f)
{
for(int i=开始;cond(i);i++)
{
f(t,i);
}
返回t;
}
我要说的是坚持第一个版本。你所发布的内容太聪明了,对阅读代码的人来说不会立即有用
您甚至可以更进一步,删除“var”:
我预测整个“流畅界面”时尚将是2000年代的“匈牙利符号”。我个人认为它看起来不太干净,如果你有多个开发人员,每个人都有自己的偏好,那么它有可能变得非常不一致。原文更具可读性
最简单的API更改是将FindControl()返回的对象设置为生成器样式的对象(其中所有set方法都返回“this”):
看起来你的同事是个兰姆达迷。我认为可读性的问题是主观的,我个人对你所做的没有异议。如果你的组织“批准”它,我会考虑使用它。
我认为这个概念是合理的,如果你把“With”改为“Let”,它会更“实用”或“F#ish”。个人意见
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.Let(d => d.Visible = true)
.Let(d => d.SelectedValue = "123");
Page.FindControl(“LocationDropDownList”)
卡斯塔斯先生()
.Let(d=>d.Visible=true)
.Let(d=>d.SelectedValue=“123”);
小注释。根据个人经验,我会改变:
if(isAdmin)
ddl.SelectedValue = "111";
到
或
这将节省您调试的时间
DropDownList ddl = (DropDownList) Page.FindControl("ddlName");
Page.FindControl("LocationDropDownList")
.setVisible(true)
.setSelectedValue(isAdmin ? "111" : "123");
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.Let(d => d.Visible = true)
.Let(d => d.SelectedValue = "123");
if(isAdmin)
ddl.SelectedValue = "111";
if(isAdmin) {
ddl.SelectedValue = "111";
}
if(isAdmin)
{
ddl.SelectedValue = "111";
}
With(Page.FindControl("LocationDropDownList") as DropDownList)
{
Visible = true;
SelectedValue = "123";
if(isAdmin)
Add(new ListItem( "111"));
}
Page.FindDropDownList("LocationDropDownList")
.setVisible(true)
.setAdminSelectedValue("111")
.setSelectedValue("123")