C#,ASP.Net 开发笔记
1. 类方法与扩展方法的区别:
TestClass test = null ;
test.ExtendMethod() ; //扩展方法不报错, 可以在方法里判断对象是否为空。
public static T FuncReturnSelf<T>(this T Self, string param)
{
...
return Self ;
}
2.Serializable Attribute 和 ISerializable 的区别:
ISerializable 可以序列化整个对象的属性。包括父对象。 是比较完整的序列化。
3. 事件委托 还是 配置接口实现?
底层要把功能开放到高层的实现方案: 一是 通过配置,在 Config中配置出 实现某接口的实现,在底层反射出对象实例(重点缓存对象),调用某方法。对于需要高层自定义代码很多的情况下,比较实用。
如果只需要高层某一个功能,或函数,可以暴露一个事件委托出来, 让高层实现该事件,即可。
4. 属性名,方法名,类名 在同一个类里, 不能同名.
如果子类的属性名与父类的方法名同名,则会报警告. 但是不妨碍使用.
5. 业务逻辑中要把 可以先进行非法条件的判断, 使判断和业务逻辑分开.
6. Mvc是一种思想,可以应用到很多地方
如: 在业务逻辑中,定义一个Model, 在业务处理层之间使用这个Model,在业务层处理数据,在视图层处理消息.
7. 约定胜于配置.
8. 基于漏斗模型的 IO.
即严谨的输出,宽松的输入.
举例:
public string proc ( string msg)
{
return msg.Trim() ; //严谨些
}
public check( string msg)
{
if ( msg.Trim() == "Edit") return true ; //宽松些。
else return false ;
}
9. 从技术上规避业务失误.
比如并发性.业务场景: 用户每年上传一个固定文件名的文件. 开发人员理所当然的以固定文件名保存在固定文件夹下. 最起码的 lock 一下.
10. 反射创建泛型类
var type = typeof(SystemException); var obj = Activator.CreateInstance( typeof(List<>).MakeGenericType(new Type[] { type }), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, null, null);
11. lock 会对多CPU,多核CPU 进行互斥.
12.字典的初始化
Dictionary<int, StudentName> students = new Dictionary<int, StudentName>() { { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}}, { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}}, { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}} };
13. 四舍五入的问题:
采用 (int)( value + 0.5) 方法进行四舍五入取整.
14.之前调试遇到的这个问题,居然再次发生,居然忘了,敢紧记下.
自定义类型转换时,采用的是明确的数据类型,如:
public static implicit operator StringLinker(string StringOne)
{
return new StringLinker(StringOne) ;
}
但是如果 String 的值,在中间过程被装箱为 object , 那么: object obj= value ; var result = (StringLinker)obj ; 这行代码不会触发类型转换,因为StringLinker定义的转换方法没有从object 转到StringLinker。 需要 (StringLiner)(string)obj ; 如果采用泛型,用泛型转换是无效的. var result = (StringLinker)(D)obj ; 悲催.!
同样的问题,还出现在扩展方法上,当扩展方法名和类中出现的方法重名时,扩展方法名失效。如下:
public static string ToJson(this object obj){ return obj.ToJsonString();}
public class MyOqlSet
{
public string ToJson(){ return this.ToJsonString(); }
}
var set = new MyOqlSet() ;
set.ToJson() ;
这时, MyOqlSet.ToJson() 方法起作用。
如果是这样:
public string Serialize(object obj )
{
obj.ToJson() ;
}
这时,扩展方法就起作用了。
15.Mvc2 一个设计不太好的地方
当URL路由是这样的时候: {Controller}/{Action}/{uid}.aspx , Action方法必须是 public ActionResult Add(string uid)
其中方法参数的名字就是路由中 uid .没有表意性. 对于不同Action uid 的含义是不同的. 这是一个不舒服的地方
想想这样做也是有原因的.它会根据URL参数和方法参数进行匹配.如:
Admin/Dept/List.aspx?Type=All , 则会匹配: public ActionResult List(string uid , string Type )
但如果还同时存在 public ActionResult Add(string uid) , 则会报错. 这是第二个不舒服的地方
16. C# 不能实现的方法
1. 两个 IEnumerable 相加 ,相减 采用 a + b , a -b 格式。
这个可以实现一个类,继承自: List , 重载 + , - 运算符。
17.尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
亲身在项目里遇到这个问题,分析出的原因是,通过 Emit 对 Null 对象进行赋值操作。
18.VS2010 快捷键记录
下一个错误: Ctrl + Shift + F12 , 在重构时,可能会有大量错误,用此可快速定位。
注释,取消注释: Ctrl+C,Ctrl+K
项目中引用选中单词的方法: Shift+Ctrl+F12 。 偶然遇到的。
在VS中设置出错自动断点: Ctrl+Alt+E。
19 设置泛型参数的技巧
如想定义如下方法:
public MyOqlSet LoadDictList<TKey,TValue>( List<IDictionary<TKey,TValue>> Source ){ return null ;}
这样定义时,要求传入参数也必须是严格的 List<IDictionary<TKey,TValue>> ,以下会编译不通过:
new MyOqlSet().LoadDictList( new List<Dictionary<string,string>>() ) ;
改为泛型约束,如下定义:
public MyOqlSet LoadDictList<T>( List<T> Source) where T: IDictionary { return null ;}
即可。
20 Transaction.Current
仅能获取到当前的 TransactionScope ,对于 DbTransaction 则无能为力,只能在当前连接上判断: conn.Transaction
21 分布式事务
http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscope(VS.80).aspx
上面这个例子犯一个很大的错误, 即: 吃掉了错误。
在出现异常时,就不应该 scope.Complete 了。
正确的做法是:
using ( var tran = new TransactionScope())
{
try
{
proc1();
dbr.Insert.Execute();
tran.Complete();
}
catch
{
Log();
}
}
另外: 测试发现: 如果 proc1 中使用了 事务,即使在存储过程中提交了事务,在dbr.Insert 出错, 存储过程的操作也会回滚。 并且抛出错误。
22 显式实现接口
显式实现的接口,不能直接调用,像 string 实现的 IConvertible , 如果要调用,需要: ( "hello" as IConvertible).ToSingle(null) ;
23 引用对象传递时,函数只能改变其内容,而不能改变其地址
static void Main(string[] args) { var dict = new Dictionary<string, string>(); update(dict); dict.All(o => { Console.WriteLine(o.Key + ":" + o.Value); return true; }); } private static void update(Dictionary<string, string> dict) { dict = new Dictionary<string, string>(); dict["id"] = "1"; }
上面由于重新指定了dict 的地址,导致Main中不会输出任何内容。 把 dict 初始化去掉就可以达到目的了。
24 隐式基类
Array 是数组的 隐式基类
ValueType 是值类型的 隐式基类
Enum 是 enum枚举的 隐式基类
MulticastDelegate 是 delegate 的基类。
25 Mvc的 Server.Transfer功能
可以使用 Server.TransferRequest 方法实现。
26 反射获取属性时,得到重复的属性值
如果类型在定义属性时,使用和基类相同的属性定义,且使用 new 进行了覆盖。(基类属性非虚) ,那么: 在使用 type.GetProperties(BindingFlags.Public | BindingFlags.Instance) 时,会得到两个属性值。 子类属性在前,基类在后。
要避免这一点,可认使用: System.ComponentModel.TypeDescriptor.GetProperties 方法。 如果基类属性与子类属性相同时,它返回子类属性。
27 Dos续行符
http://www.newsmth.net/nForum/#!article/DOS/16444
Dos续行符是: ^
Js的续行符是 \
28. 二进制的位设置
二进制 增加某位设置: a | b ;
二进制 减少某位设置: a & ( ~b) ;
29. FileSystemWatcher
30. 类仅供某个类调用。
public class 调用类
{
private class 被调用类{
internal void 方法(){}
}
//随便调用吧。
}
31. 逆变 协变
http://www.cnblogs.com/LoveJenny/archive/2012/03/13/2392747.html
结论:
<out T> 表示 T只能做为 返回值。
<in T> 表示 T只能作为 输入值。
32. Web.Config文件中关于大小的单位
一般是 KB,比如 maxRequestLength
而程序中文件大小,一般是 Byte,比如文件的流长度。
33.多线程
影响线程池线程数量的关键是 ThreadPool 的SetMinThreads 属性,而不是 SetMaxThreads 。 SetMaxThreads 会根据需要慢慢增长。
QueueUserWorkItem 和 Action,Func 的 BeginInvoke 是一样的: 受线程池 SetMinThreads 影响, 在调用后,马上进入线程池队列等待执行,并马上返回。 目前无法控制队列大小。
34. 关于 Response 的 Context-Type chunk
35. RouteDebugger 版本升级后的使用方法
版本1.0:
Application_Start : //RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
版本2.0
Application_Start: RouteDebug.PreApplicationStart.Start();
web.config 增加: <add key="RouteDebugger:Enabled" value="true" />
36. 继承字典对象的属性
字典在序列化为Json时,是按键值对来序列化的。所以字典属性会被忽略。
把字典的属性据保存到 键值对上,是一个好方法。如:
public class DbSummaryModel : StringDict { public string TableSummary { get { return this["#_TableSummary"]; } set { this["#_TableSummary"] = value; } } }
作者:NewSea 出处:http://newsea.cnblogs.com/
QQ,MSN:iamnewsea@hotmail.com 如无特别标记说明,均为NewSea原创,版权私有,翻载必纠。欢迎交流,转载,但要在页面明显位置给出原文连接。谢谢。 |