更流畅的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")