More fluent C# / .NET

2020-02-17 05:39发布

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

标签: c#
21条回答
等我变得足够好
2楼-- · 2020-02-17 06:06

It's an interesting use of extensions, and I appreciate it on that merit alone. I'm not sure I'd use it, but if your team likes it, then by all means, use it.

查看更多
淡お忘
3楼-- · 2020-02-17 06:08

I guess I fail to see what the new versions get you. The original is pretty clear and is less wordy. I would guess that it would be faster as well. I would avoid using (abusing?) language features like this unless there is a clear benefit.

查看更多
Ridiculous、
4楼-- · 2020-02-17 06:08

Minor note. From personal experience, I'd change:

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

to

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

or

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

This will save you time in debugging sooner or later.

查看更多
太酷不给撩
5楼-- · 2020-02-17 06:08

I think the question of readability is subjective and I personally have no issue with what you've done. I would consider using it if your organization "approved" it.

I think the concept is sound and if you changed "With" to "Let" it would be more "functional" or "F#-ish". Personal opinion.

Page.FindControl("LocationDropDownList")    
    .CastAs<DropDownList>()    
    .Let(d => d.Visible = true)  
    .Let(d => d.SelectedValue = "123");
查看更多
来,给爷笑一个
6楼-- · 2020-02-17 06:09

My 2 cents: It looks fine, my only comment is that "With" kind of implies something like "Where" or "Having" when you are actually setting a property. I'd suggest a method name of something like "Do", "Execute" or "Set" but maybe thats just my odd world view.

How about:

Page.WithControl<DropDownList>("LocationDropDownList")
    .Do(d => d.Visible = true)
    .Do(d => d.SelectedValue = "123")
    .DoIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
查看更多
男人必须洒脱
7楼-- · 2020-02-17 06:11

They're just different coding styles, what do you mean by "too big a departure"? Departure from what? From what you're used to? Only you can decide that. I will say that VB's With block has done more harm than good to code readability, and I would not try to replicate the behavior in C#, but that's just my preference.

I pretty much always use this for FindControl (yeah, strongly typed to RepeaterItem, it doesn't have to be, but that's the only thing I ever use it for anyway):

public static T FindControl<T>(this RepeaterItem item, string id) 
{
    return item.FindControl(id) as T;
}

And invoke it like so:

Literal myLiteral = e.Item.FindControl<Literal>("myLiteral");
查看更多
登录 后发表回答