新足迹

 找回密码
 注册

精华好帖回顾

· 从中国到澳洲,挨踢10年中国篇(全文完)-10月22日更新随笔312楼 (2009-9-7) Melbourner1978 · 新移民墨尔本艰苦中介租房经历和tips分享 (2008-10-14) Rafe
· 大枣回家过年之感悟 (2007-4-8) xzlzxzlz · 一次心血来潮的旅行 -- 泰国记游 (2009-10-16) astina
Advertisement
Advertisement
查看: 2936|回复: 59

C# 的小疑惑,让你写更美更有效的代码  关闭 [复制链接]

2010年度奖章获得者

发表于 2011-2-26 16:34 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
We all have those little wonders in our .NET code, those small tips and tricks that make code just that much more concise, maintainable, or performant. Many of you probably already know of some of these, but many folks either overlook them or just don’t know about them, so this article is a refresher.

1. IsNullOrEmpty() VS IsNullOrWhiteSpace()
string str1 = "";
string str2 = " ";
string str3 = "\r\n";

bool res1 = String.IsNullOrEmpty(str1);
bool res2 = String.IsNullOrEmpty(str2);
bool res3 = String.IsNullOrEmpty(str3);

Response.Write(String.Format("Result 1:{0}", res1));
Response.Write(String.Format("<br />Result 2:{0}", res2));
Response.Write(String.Format("<br />Result 3:{0}", res3));

The result is: Result 1:True Result 2:False Result 3:False

2. The As Cast

How many times have you seen code like this:

if (employee is SalariedEmployee)
{
        var salEmp = (SalariedEmployee)employee;
}

This is redundant because you are checking the type twice. Once in the is check and once in the cast. Whenever you find yourself going down this path, prefer the as cast. This handy cast will cast the type if the types are compatible, or return null if not:

var salEmployee = employee as SalariedEmployee;
if (salEmployee != null)
{
    pay = salEmployee.WeeklySalary;
}


3. The Stopwatch Class

How many times have you wished to log how long a particular piece of code took to execute? Maybe you are trying to track average request time or some such metric, or maybe send a warning message when a stored procedure takes longer than 1 second to execute.

Well, you could do it with DateTime like so:
DateTime start = DateTime.Now;
SomeCodeToTime();
DateTime end = DateTime.Now;
Console.WriteLine("Method took {0} ms", (end - start).TotalMilliseconds);


The Stopwatch class makes it clean and easy to use the high resolution timer through the convenience of a C# class:

var timer = Stopwatch.StartNew();
SomeCodeToTime();
timer.Stop();
Console.WriteLine("Method took {0} ms", timer.ElapsedMilliseconds);

4. Static Class Modifier

Let’s say you’re writing an XmlUtility class, and the goal of this class is to be able to serialize an object to a string of XML without having to do the encoding and serializing each time. You may come up with something like this:

public class XmlUtility
{
        public string ToXml(object input)    {
                //XML serialization logics
                return xml;
        }
}

var xmlUtil = new XmlUtility();
string result = xmlUtil.ToXml(someObject);


This is just typical XML serialization code. The problem is, we have to create this class to use it:
That’s not very elegant usage since the class instance has no state. Of course you could avoid this by making the method static and a private constructor so that it can’t be created:
public class XmlUtility
{
        private XmlUtility() {}
        public static string ToXml(object input)
        {
                return xml;
        }
}

Well, that prevents someone from incorrectly instantiating or inheriting our class, which is good. But that empty private constructor is kind of ugly and forced, and there’s nothing that prevents a modifier from adding a non-static method by mistake:

public T FromXml<T>(string xml) {...}

Since this was not declared static, but the constructor is not visible, this method can never be used. Enter the static class modifier. If you put the word static before the class keyword, it tells the compiler that the class must only contain static methods, and cannot be instantiated or inherited.


public static class XmlUtility
{
    public static string ToXml(object input) { return xml; }
}

now it cannot be instantiated and no one can come in later and accidentally add an instance method, property, constructor by mistake!

5. Generic Delegates

The great thing about delegates is they can make classes so much more reusable than inheritance can. For example, let’s say you want to design a cache class and that class will contain a method, provided by the class’s user, that will determine if a cache item has expired and can be removed. You could provide an abstract method that the user has to provide, but this means that the user would have to extend your class and override the method, which means a lot of extra work for providing that functionality. In addition, this means you can’t mark your class as sealed to protect it from other non-related changes during inheritance.

This is where delegates become really powerful, you could provide a delegate that would specify a method type that can be called to check a cache item to see if it’s expired, and then when the user instantiates your cache, they can pass in or set the delegate to the method, anonymous delegate, or lambda they want called. This way, no subclass is necessary and in fact you can seal your class to prevent unintentional changes. This makes the class much more safe and reusable.

So what does this have to do with generic delegates? Well, there are three basic “types” of delegates that appear over and over again, and rather than having to write these delegate types repeatedly, .NET has done you a big favor by making them generic so that they can be used repeatedly. This also has the added benefit of making code that depends on delegates more readable, as these generic delegates are well understood in usage and intention:

•Action – A method that takes an argument of type T and returns void – generally used to perform an action on an item.
•Predicate – A method that takes an argument of type T and returns a bool – generally used to determine if an item meets a condition.
•Func – A method that returns a result of type TResult – generally used to generate values.

Note that these are the base forms of these generic delegates, and there are versions that take multiple parameters for each, the main thing that is constant is that Action returns void, Predicate returns bool, and Func returns a specified result.

So, to our cache example, say you wanted to write that cache that accepts a caching strategy, you would want a delegate that operates on an argument and returns a bool as to whether it has expired, that sounds like a Predicate:

public sealed class Cache<T>
{
        private ConcurrentDictionary<string, CacheItem<T>> _cache;
        private Predicate<CacheItem<T>> _expirationStrategy;
        public Cache(Predicate<CacheItem<T>> expirationStrategy)
        {
                 // set the delegate
                 _expirationStrategy = expirationStrategy;
        }
}

var cache = new Cache<int>(item => DateTime.Now - item.LastAccess > TimeSpan.FromSeconds(30));


In fact, we can create as many caches we want with as many expiration strategies as we can think of and never need to subclass! Know and use your generic delegates and it will really increase the re-usability of your classes. In fact, any time when you are thinking of adding an abstract method and needing to provide functionality in a sub-class, if all you are doing is providing “hooks”, consider generic delegates instead.

[ 本帖最后由 dalaohu 于 2011-2-26 18:51 编辑 ]

评分

参与人数 2积分 +9 收起 理由
乱码 + 3 感谢分享
iami + 6 感谢分享

查看全部评分

足迹 Reader is phenomenal. If you never used, you never lived 火速下载
Advertisement
Advertisement
头像被屏蔽

禁止发言

发表于 2011-2-26 17:11 |显示全部楼层

斗胆问一下,第二个例子里面的code,前后似乎都是一样的

此文章由 iami 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 iami 所有!转贴必须注明作者、出处和本声明,并保持内容完整

评分

参与人数 1积分 +5 收起 理由
dalaohu + 5 你太有才了,真的一模一样

查看全部评分

2010年度奖章获得者

发表于 2011-2-26 17:52 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
多谢,已经改了 :)

发表于 2011-2-27 11:28 |显示全部楼层
此文章由 jerryclark 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 jerryclark 所有!转贴必须注明作者、出处和本声明,并保持内容完整
第二个例子有一个缺陷,不嫩用在struct上面。比如DateTime,等等

评分

参与人数 1积分 +3 收起 理由
dalaohu + 3 我很赞同

查看全部评分

2010年度奖章获得者

发表于 2011-2-27 14:21 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 jerryclark 于 2011-2-27 12:28 发表
第二个例子有一个缺陷,不嫩用在struct上面。比如DateTime,等等


你说的对。

as 就是用于 reference type 的。
value type的 as 不支持。
足迹 Reader is phenomenal. If you never used, you never lived 火速下载

发表于 2011-2-27 17:21 |显示全部楼层
此文章由 oldqin 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 oldqin 所有!转贴必须注明作者、出处和本声明,并保持内容完整
好文,收藏先,有空先把那个Stopwatch用起来
Advertisement
Advertisement
头像被屏蔽

禁止访问

发表于 2011-2-28 10:33 |显示全部楼层

好文,收藏先

此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Stopwatch 没看出有什么好处

2010年度奖章获得者

发表于 2011-2-28 11:15 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Stopwatch 属于那种让你的code 更优雅的。
也短很多。

你的ID回来了没?
头像被屏蔽

禁止访问

发表于 2011-2-28 14:12 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
codes短了么??没看出来啊?

ID回来不了了。 我又注册了一个,哈哈。
管管相互有牵连啊。斑竹们都不能说,说了直接封ID. 那个阿丝说我屡教不改。我是据理力争。可是没办法,面对专权,草民无可奈何阿。

原帖由 dalaohu 于 2011-2-28 12:15 发表
Stopwatch 属于那种让你的code 更优雅的。
也短很多。

你的ID回来了没?

评分

参与人数 2积分 +10 收起 理由
mylt + 5 支持
乱码 + 5 安慰一下

查看全部评分

发表于 2011-2-28 14:52 |显示全部楼层

回复 9# 的帖子

此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Poor guy

特殊贡献奖章

发表于 2011-2-28 15:08 |显示全部楼层
此文章由 kr2000 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 kr2000 所有!转贴必须注明作者、出处和本声明,并保持内容完整
你被封了几次,怎么屡教不改了?
你把情况说说,我们it版的帮你争回来
原帖由 一切顺利 于 2011-2-28 15:12 发表
codes短了么??没看出来啊?

ID回来不了了。 我又注册了一个,哈哈。
管管相互有牵连啊。斑竹们都不能说,说了直接封ID. 那个阿丝说我屡教不改。我是据理力争。可是没办法,面对专权,草民无可奈何阿。

Advertisement
Advertisement

2010年度奖章获得者

发表于 2011-2-28 15:10 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 kr2000 于 2011-2-28 16:08 发表
你被封了几次,怎么屡教不改了?
你把情况说说,我们it版的帮你争回来


你是说黑进数据库去?
足迹 Reader is phenomenal. If you never used, you never lived 火速下载
头像被屏蔽

禁止访问

发表于 2011-2-28 15:10 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 flyspirit 于 2011-2-28 15:52 发表
Poor guy


没事,没事。其实,我有什么损失?? 我才不在乎什么积分,什么族。这些东西只能对喜欢幻想的人起作用。来这就是和各位大师学习的。封了我,注册一个再来,哈哈。

特殊贡献奖章

发表于 2011-2-28 15:12 |显示全部楼层
此文章由 kr2000 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 kr2000 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我是说讲道理去,人多力量大
神马情况要永久封id?
头像被屏蔽

禁止访问

发表于 2011-2-28 15:12 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 kr2000 于 2011-2-28 16:08 发表
你被封了几次,怎么屡教不改了?
你把情况说说,我们it版的帮你争回来


谢谢啊。IT版的人最真诚,所以喜欢来这里。 这事情说来话长。大伙要是都喜欢听,我回头说说。

评分

参与人数 1积分 +5 收起 理由
乱码 + 5 再补点血,早日升靴吧~~

查看全部评分

2010年度奖章获得者

发表于 2011-2-28 15:15 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
一切顺利也太傻了吧。

叫 澳毒 多好
Advertisement
Advertisement
头像被屏蔽

禁止访问

发表于 2011-2-28 15:15 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-2-28 16:10 发表


你是说黑进数据库去?


这个,得要技术强人,或者内部人士。
头像被屏蔽

禁止访问

发表于 2011-2-28 15:16 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-2-28 16:15 发表
一切顺利也太傻了吧。

叫 澳毒 多好


不许污辱我。

2010年度奖章获得者

发表于 2011-2-28 15:18 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我上次有个DOS 工具, 差点想小式一把, 可是我太正直了。
头像被屏蔽

禁止访问

发表于 2011-2-28 15:20 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-2-28 16:18 发表
我上次有个DOS 工具, 差点想小式一把, 可是我太正直了。


谢谢啊。违法的事,还是别干。不过,要是从美国发起攻击。。。。。。。。。

2010年度奖章获得者

发表于 2011-2-28 15:23 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
其实我只是想找出影迷版版主。 要不顺带把你也从大牢里就出来?
Advertisement
Advertisement
头像被屏蔽

禁止访问

发表于 2011-2-28 15:28 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-2-28 16:23 发表
其实我只是想找出影迷版版主。 要不顺带把你也从大牢里就出来?


好人啊。兄弟出来哪天,一定请你吃。。。。。。。。。。。。。。。麦当劳。。。。。。。。。。。。。的。。。。。。。。。。。。。。。ice cream cone

2010年度奖章获得者

发表于 2011-2-28 15:34 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
soft serve cone 以前是5分钱的。

现在挺贵的咯, 你确定?
头像被屏蔽

禁止访问

发表于 2011-2-28 15:36 |显示全部楼层
此文章由 一切顺利 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 一切顺利 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-2-28 16:34 发表
soft serve cone 以前是5分钱的。

现在挺贵的咯, 你确定?


我到时候先看价格,超过$2,我就借故溜走。

特殊贡献奖章

发表于 2011-2-28 15:37 |显示全部楼层
此文章由 kr2000 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 kr2000 所有!转贴必须注明作者、出处和本声明,并保持内容完整
你这样不行滴
就算成功了也是通缉犯啊
要靠正路
要研究版规,帮澳贼脱罪,至少减个刑神马的
终身监禁太重了

发表于 2011-2-28 15:39 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 kr2000 于 2011-2-28 16:37 发表
你这样不行滴
就算成功了也是通缉犯啊
要靠正路
要研究版规,帮澳贼脱罪,至少减个刑神马的
终身监禁太重了


嗯,同意,争取用原来的ID.

kr2000,你原来留得backdoor现在可以派上用场了

评分

参与人数 1积分 +3 收起 理由
kr2000 + 3 嘘,不要乱说

查看全部评分

Advertisement
Advertisement

特殊贡献奖章

发表于 2011-2-28 15:41 |显示全部楼层
此文章由 kr2000 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 kr2000 所有!转贴必须注明作者、出处和本声明,并保持内容完整
乱码兄正直的形象,适合做澳贼的担保

澳贼你把情况说出来呀,要不乱码做了你的担保成了罪人就麻烦了
原帖由 乱码 于 2011-2-28 16:39 发表


嗯,同意,争取用原来的ID.

kr2000,你原来留得backdoor现在可以派上用场了

2007 年度奖章获得者 参与宝库编辑功臣 飞天奖章

发表于 2011-2-28 15:42 |显示全部楼层
此文章由 astina 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 astina 所有!转贴必须注明作者、出处和本声明,并保持内容完整
路过一下,有的玩笑不能乱开的,有关同学自己注意一下

发表于 2011-2-28 15:49 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 astina 于 2011-2-28 16:42 发表
路过一下,有的玩笑不能乱开的,有关同学自己注意一下


Astina,澳贼应该从这件事情上吸取教训了,我相信他以后不会这么冲动。

澳贼在IT版一直表现不错,我建议总版主酌情把他放出来。

谢谢!!

2007 年度奖章获得者 参与宝库编辑功臣 飞天奖章

发表于 2011-2-28 15:50 |显示全部楼层
此文章由 astina 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 astina 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 乱码 于 2011-2-28 16:49 发表


Astina,澳贼应该从这件事情上吸取教训了,我相信他以后不会这么冲动。

澳贼在IT版一直表现不错,我建议总版主酌情把他放出来。

谢谢!!

谢谢你担保他,不过不知道你是否了解事情始末?
于无声处听惊雷

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部