更流畅的C#/。NET [英] More fluent C# / .NET

查看:96
本文介绍了更流畅的C#/。NET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一位同事想出了这个,我不知道别人怎么想?就个人而言,我觉得很有意思,但不知道这是太大的背离?下面的代码示例。扩展方法在底部。



常规的想法吧。可以添加其它扩展方法

  VAR DDL = Page.FindControl(LocationDropDownList)作为DropDownList的?; 

ddl.Visible = TRUE;
ddl.SelectedValue =123;

如果(isAdmin)
DDL .SelectedValue =111;



变成了:

  Page.FindControl(LocationDropDownList)
.CastAs<&DropDownList的GT;()
。随着(D => d.Visible = TRUE)
。随着(D = > d.SelectedValue =123)
.WithIf(isAdmin,D = GT; d.Items.Add(新的ListItem(管理,1)));

或者



  Page.FindControl(LocationDropDownList)
.CastAs<&DropDownList的GT;()
。随着(D =>
{
d.Visible = TRUE;
d.SelectedValue =123;
})
.WithIf(isAdmin,D = GT; d.SelectedValue =111);



扩展方法:

 公共静态TResult CastAs< TResult>(这个obj对象),其中TResult:类
{
回报的obj为TResult;
}

公共静态T带< T>(此T(T),动作< T>动作)
{
如果(动作== NULL)
抛出新的ArgumentNullException(行动);

动作(T);

返回吨;
}

公共静态牛逼WithIf< T>(此T(T),布尔条件,动作< T>动作)
{
如果(动作== NULL)
抛出新的ArgumentNullException(行动);

如果(条件)
动作(T);

返回吨;
}


解决方案

当中我的拇指规则字迹清晰的代码是:摆在语句中的所有副作用;非语句表达式应该没有副作用。



您程序的第一个版本显然遵循这一规则。第二个版本明显违反它。



另外一个念头:如果我读,就像你所显示的代码的代码,我自然会假设代码的目的是要建立一个延迟加载这代表这些操作评估结构 - 这正是为什么在C#3查询内涵是建立在这样的。查询表达式的结果是代表查询的延迟应用中的对象。



如果你的目的是捕捉到的我选择的时刻后执行的递延方式,这些副作用的概念,那么这是一个明智的做法。本质上讲你建立一个副作用的单子。如果你的目的仅仅是为了提供对翘首执行的代码不同的语法,那么这只是混乱,冗长和不必要的。


A co-worker of mine came up with this and I wonder what others think? Personally, I find it interesting but wonder if it is too big a departure? Code examples below. Extension methods at the bottom.

General thoughts please. Other extension methods that could be added?

var ddl = Page.FindControl("LocationDropDownList") as DropDownList;

ddl.Visible = true;
ddl.SelectedValue = "123";

if(isAdmin)
    ddl  .SelectedValue = "111";

Becomes:

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")));

Or:

 Page.FindControl("LocationDropDownList")
       .CastAs<DropDownList>()
       .With(d =>
       {
           d.Visible = true;
           d.SelectedValue = "123";
       })
       .WithIf(isAdmin, d => d.SelectedValue = "111");

Extension methods:

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;
}

解决方案

Amongst my rules of thumb for writing clear code is: put all side effects in statements; non-statement expressions should have no side effects.

Your first version of the program clearly follows this rule. The second version clearly violates it.

An additional thought: if I were to read code like the code you've displayed, I would naturally assume that the purpose of the code was to build up a lazily-evaluated structure which represented those operations -- this is exactly why query comprehensions in C# 3 are built in this way. The result of the query expression is an object representing the deferred application of the query.

If your intention is to capture the notion of "execute these side effects in a deferred manner at a later moment of my choosing", then this is a sensible approach. Essentially what you're building up is a side-effecting monad. If your intention is merely to provide a different syntax for the eagerly executed code, then this is just confusing, verbose and unnecessary.

这篇关于更流畅的C#/。NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆