突发奇想,搞个C#版的和它PK下。
抛砖引玉:
1. 使用as,而非is
object o = GetFromCache("A_KEY");
EmployeeInfo employee = o as EmployeeInfo;
if(employee != null) {
// TODO: 代码
}
2. 使用DataReader读取数据
using(SqlDataReader reader = SqlHelper.ExecuteReader(cmd)) {
while(reader.read()) {
// TODO: 读取当前行的数据
}
}
3. 尽量使用强类型集合(包括泛型集合),而非DataTable
using(SqlDataReader reader = SqlHelper.ExecuteReader(cmd)) {
Ilist<EmployeeInfo> list = new List<EmployeeInfo>();
while(reader.read()) {
list.add(new EmployeeInfo(
reader.getInt32(0)
// 其它字段
));
}
}
4. 使用StringBuilder操作频繁变动的字符串,但以下情况例外
string s = "str1" + "str2" + "str3" + "str4"; // 这段代码不需要使用StringBuilder,因为编译后的代码为 string s = "str1str2str3str4";
445 个解决方案
#1
。。。
#2
刚给control写了个扩展方法,按回车发送tab键的 ^_^
public static class ControlExtensions
{
public static void SendTabKey(this Control control, Keys key)
{
if (key == Keys.Enter)
SendKeys.Send("{TAB}");
}
}
#3
占座
#4
遍歷control
private void PanelClear(Control c)
{
foreach (Control cc in c.Controls)
{
if (cc.GetType() != typeof(Panel))
{
PanelClear(cc);
}
else
{
((Panel)cc).Visible = false;
}
}
}
#5
1)对所有类都重写ToString()方法,这样在调试,绑定中都非常有用。
2)使用Enum代替奇迹数
先说两点。想起来再加。
2)使用Enum代替奇迹数
先说两点。想起来再加。
#6
找出是否存在某個窗體FORM
for (int j = 0; j < Application.OpenForms.Count; j++)
{
if (Application.OpenForms[j].Name.Equals("FNO31000"))
{
fno3100 = true;
}
}
If (fno3100 = true)
FNO31000 fno = (FNO31000)Application.OpenForms["FNO31000"]
#7
插队
#8
lz写的第4点,用String.Format() 如何?
String.Format("{0}{1}{2}{3}", str0, str1, str2, str3);
#9
留个名,学习
#10
將datagridview的某個checkbox不顯示
public void chang_COLOR(int i, string str)//將顯示為N者不顯示選取方塊
{
dataGridView1.Rows[i].Cells[str].ReadOnly = true;
DataGridViewCell cell = new DataGridViewTextBoxCell();
cell.Style.BackColor = Color.Wheat;
//cell.ReadOnly = true;
cell.Value = "N";
cell.Style.BackColor = Color.White;
dataGridView1.Rows[i].Cells[str] = cell;
dataGridView1.Rows[i].Cells[str].Style.ForeColor = Color.White;
dataGridView1.Rows[i].Cells[str].Style.SelectionBackColor = Color.White;
dataGridView1.Rows[i].Cells[str].Style.SelectionForeColor = Color.White;
}
#11
打開某個路徑下的程序
Process p = new Process();就贴这么多把
p.StartInfo.FileName = "cmd.exe"; //设定程序名
p.StartInfo.UseShellExecute = false; //关 ?Shell的使用
p.StartInfo.RedirectStandardInput = true; //重定向标 ã输 ¤J
p.StartInfo.RedirectStandardOutput = true; //重定向标 ã输 ¥X
p.StartInfo.RedirectStandardError = true; //重定向错 ?输 ¥X
p.StartInfo.CreateNoWindow = true; //设置不显 ¥Ü窗口
p.StartInfo.WorkingDirectory = @"E:\";
p.Start(); //启 ?
p.StandardInput.WriteLine("新增文字文件.bat");
p.StandardInput.WriteLine("exit");
#12
再来一些
自认为比较高级的:
1. 字符串留用技术
字符串留用技术用来处理大量的字符串,而这些字符串中又会有许多重复的字符,例如:
"str1", "str2", ... , "str100" 共10,000个这样的字符,毫无疑问,其实就99个字符
这种情况可以使用到字符串留用技术,会提到性能
2. 数组永远是0基的
3. 使用多线程或异步操作的时候使用线程池的QueueUserWorkItem()方法将需要执行的任务排队,而不是手动去Start一个线程
1. 字符串留用技术
字符串留用技术用来处理大量的字符串,而这些字符串中又会有许多重复的字符,例如:
"str1", "str2", ... , "str100" 共10,000个这样的字符,毫无疑问,其实就99个字符
这种情况可以使用到字符串留用技术,会提到性能
2. 数组永远是0基的
3. 使用多线程或异步操作的时候使用线程池的QueueUserWorkItem()方法将需要执行的任务排队,而不是手动去Start一个线程
#13
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
public delegate bool DelegateTest(object obj1, object obj2);
class Class1
{
static void Main()
{
Employee[] Employees =
{
new Employee("huguo",1000000),
new Employee("lili",20000),
new Employee("lulu",30000),
new Employee("xixi",50000),
new Employee("jianjian",10000),
new Employee("yoyo",9000)
};
//委托DelegateTest代理的方法是Greate
DelegateTest MyTest = new DelegateTest(Employee.Greate);
Sorter MySort = new Sorter();
//冒泡算法中第一个参数是对应Employees数组信息,第二个参数是委托
MySort.Sort(Employees, MyTest);
for (int m = 0; m < Employees.Length; m++)
{
Console.WriteLine(Employees[m].ToString());
}
}
}
class Employee
{
public string Name;
public int Salary;
public Employee(string Name, int Salary)
{
this.Name = Name;
this.Salary = Salary;
}
//用override重写string方法
public override string ToString()
{
return string.Format(Name + ",{0:C},", Salary);
}
//定义一个方法,如果obj2传过来的 Salary大于obj1就返回true;
public static bool Greate(object obj1, object obj2)
{
Employee Employee1 = (Employee)obj1;
Employee Employee2 = (Employee)obj2;
return (Employee2.Salary > Employee1.Salary) ? true : false;
}
}
class Sorter
{
public void Sort(object[] ArrayObj, DelegateTest Test)
{
//下面就是冒泡算法啦
for (int i = 0; i < ArrayObj.Length; i++)
{
for (int j = i + 1; j < ArrayObj.Length; j++)
{
if (Test(ArrayObj[j], ArrayObj[i]))
{
object Temp = ArrayObj[i];
ArrayObj[i] = ArrayObj[j];
ArrayObj[j] = Temp;
}
}
}
}
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/07/25/4380283.aspx
#14
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
CreateNum();
}
}
//在从1到20间随机生成6个互不相同的整数。
public void CreateNum()
{
ArrayList MyArray = new ArrayList();
Random random = new Random();
string str = null;
//循环的次数
int Nums = 6;
while (Nums > 0)
{
int i = random.Next(1, 9);
if (!MyArray.Contains(i))
{
if (MyArray.Count < 6)
{
MyArray.Add(i);
}
}
Nums -= 1;
}
for (int j = 0; j <= MyArray.Count - 1; j++)
{
str += MyArray[j].ToString();
}
Response.Write(str);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/05/09/4164277.aspx
#15
//方法1
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ReplaceStr();
}
}
public void ReplaceStr()
{
ArrayList MyArray = new ArrayList();
MyArray.Add("123");
MyArray.Add("aaa");
if (MyArray.Contains("aaa"))
{
MyArray.Remove("aaa");
MyArray.Add("bbb");
}
for (int i = 0; i <= MyArray.Count - 1; i++)
{
Response.Write(MyArray[i].ToString());
}
}
//方法2
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ReplaceStr();
}
}
public void ReplaceStr()
{
string [] tm = new string[] { "123", "aaa" };
for (int i = 0; i < tm.Length; i++)
{
if (tm[i].ToString() == "aaa")
{
tm[i]=tm[i].Replace("aaa", "bbb");
}
}
for (int i = 0; i <= tm.Length - 1; i++)
{
Response.Write(tm[i].ToString());
}
}
//方法3
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string[] tm = new string[] { "123", "aaa" };
string Array=ReplaceValue(tm, "aaa", "bbb", ",");
Response.Write(Array);
}
}
public static string ReplaceValue(string[] item, string oldSv, string newSv, string separator)
{
if (item == null) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string s in item)
{
if (s == oldSv)
{
sb.Append(newSv);
sb.Append(separator);
}
else
{
sb.Append(s);
sb.Append(separator);
}
}
string returnstr = sb.ToString();
returnstr = (returnstr.EndsWith(separator)) ? returnstr.Substring(0, returnstr.Length - 1) : returnstr;
return returnstr;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/05/10/4164995.aspx
#16
效率一定没有直接赋值高,因为你的代码涉及到方法调用的开销,而且有异常。
不过,很多情况下,这个方法非常直观,大大的推荐使用。
#17
#18
学习了,先
#19
private static void PrepareCommand(MySqlConnection con,MySqlCommand mycmd,string cmdText,MySqlParameter[] cmdParams,CommandType cmdType)
{
con.Open();
mycmd.Connection = con;
mycmd.CommandText = cmdText;
mycmd.CommandType = cmdType;
if (cmdParams != null)
{
foreach (MySqlParameter param in cmdParams)
{
//if((param.Direction==ParameterDirection.InputOutput || param.Direction==ParameterDirection.Input) && (param.Value==null))
//{
// param.Value = DBNull.Value;
mycmd.Parameters.Add(param);
//}
}
}
}
#20
强贴留名。
#21
这算小技巧吧。
#22
楼上用MySql?
本人很喜欢MySql!
#23
如果实现了IDisposable的对象在访问完成后要进行关闭,则在try{...}finally{...//关闭代码},或直接调用using(...){...}。
#24
为什么用SqlDataReader而不用DataSet?
SqlDataReader持久占连接。
而且DataSet对VS控件的兼容性更强一些。
SqlDataReader持久占连接。
而且DataSet对VS控件的兼容性更强一些。
#25
学啊 不学怎么进步
#26
楼主说的不是Effective C# 上的
#27
对于第一点,有待考究。哈哈
#28
在写公共类库,使用catch时,最好不要catch(Exception e){throw e;}而使用catch{throw;},同时如果使用catch捕捉异常,最好使用catch(最具体的Exception e){...}catch(最具体的Exception e){...}...一直到所有确认的错误都能检查到 ;而不要使用catch(基类Exception e){...}
#29
推荐使用using(){}
去写实现了IDisposable的对象
非常漂亮!
#30
学习
#31
//尽量不用
string str="";
//而是
string str=string.Empty;
#32
DataSet过于强大
但是,强大是要付出代价的,哈哈
其实,DataTable内部就是用了SqlDataReader( 本人98%肯定)
#33
看不太懂。。。 插队插队
#34
一般情况下,这个问题基本上不用考虑。
但是上升到公共类库,就需要考虑语言的互操作性
也就是CLR的兼容性
如果我没有记错的话:
Catch(Exception) 只捕捉符合公共语言运行库的异常
Catch{} 则可以捕捉所有类型的异常
#35
释放连接后,DataTable是能够使用的啊,难道从头迭代到末尾了?
#36
Effective C# 原则5:始终提供ToString()(部分翻译)
Always Provide ToString()
在.Net世界里,用得最多的方法之一就是System.Object.ToStrying()了。你应该为你所有的客户写一个“通情达理”的类(译注:这里是指这个类应该对用户友好)。要么,你就迫使所用类的用户,去使用类的属性并添加一些合理的易读的说明。这个以字符串形式存在,关于你设计的类的说明,可以很容易的向你的用户显示一些关于对象的信息到:Windows Form里,Web Form里,控制台输出。这些字符说明可以用于调试。你写的任何一种类型,都应该合理的重写这个方法。当你设计更多的复杂的类型时,你应该实现应变能力更强的IFormattable.ToString(). 承认这个:如果你不重写(override)这个常规的方法,或者只是写一个很糟糕的,你的客户将不得不为你修正它。
System.Object版的ToString()方法只返回类型的名字。这并没有太多有用的信息:“Rect”,“Point”,“Size”并不会如你所想的那样显示给你的用户。但那只是在你没有为你的类重写ToString()方法时得到的。你只用为你的类写一次,但你的客户却会使用很多次。当你设计一个类时,多添加一点小小的工作,就可以在你或者是其他人每次使用时得到回报。
(译注:废话!)
======================
这一原则就不翻译了,看的有点郁闷。就是ToString()的几个重写版本。以及一些格式化输出。我觉得本书不应该讨论这些入门级的内容,所以只是读了一遍,就没有全部翻译。
大家知道要重写它就行了,最好是提供几个重载版本。回头有时间再翻译这一原则的其它内容。
给一点个人建议,一般不会在一个类的ToString上提供很多的说明,给一个名字就已经足够了,然后加一个SDK帮助。更多时候,在后面添加成员类的说明。我就在一个第三方库的ToString上看到很严谨的结构,都是在类名后面,添加一些内容和重要属性的说明。
=========================================补译:
让我们来考虑一个简单的需求:重写System.Object.ToString()方法。你所设计的每一个类型都应该重写ToString()方法,用来为你的类型提供一些最常用的文字说明。考虑这个Customer类以及它的三个成员(fields)(译注:一般情况,类里的fields译为成员,这是面向对象设计时的概念,而在与数据库相关的地方,则是指字段):
public class Customer
{
private string _name;
private decimal _revenue;
private string _contactPhone;
}
默认继承自System.Object的ToString()方法会返回"Customer"。这对每个人都不会有太大的帮助。就算ToString()只是为了在调试时使用,也应该更灵活(sophisticated)一些。你重写的ToString()方法应该返回文字说明,更像是你的用户在使用这个类一样。在Customer例子中,这应该是名字:
public override string ToString()
{
return _name;
}
如果你不遵守这一原则里的其它意见,就按照上面的方法为你所定义的所有类型重写该方法。它会直接为每个人省下时间。
当你负责任的为Object.ToString()方法实现了重写时,这个类的对象可以更容易的被添加到Windows Form里,Web Form里,或者打印输出。 .NET的FCL使用重载的Object.ToString()在控件中显示对象:组合框,列表框,文本框,以及其它一些控件。如果你一个Windows Form或者Web Form里添加一个Customer对象的链表,你将会得到它们的名字(以文本)显示出来(译注:而不是每个对象都是同样的类型名)。
Syste.Console.WriteLine()和System.String.Formate()在内部(实现的方法)是一样的。任何时候,.Net的FCL想取得一个customer的字符串说明时,你的customer类型会提供一个客户的名字。一个只有三行的简单函数,完成了所有的基本需求。
这是一个简单的方法,ToString()还可以以文字(输出的方法)满足很多用户自定义类型的需求。但有些时候,你的要求可能会更多。前面的customer类型有三个成员:名字,收入和联系电话。对System.Object.ToString()(译注:原文这里有误,掉了Object)的重写只使用了_name。你可以通过实现IFormattable(这个接口)来弥补这个不足。这是一个当你需要对外输出格式化文本时使用的接口。IFormattable包含一个重载版的ToString()方法,使用这个方法,你可以为你的类型信息指定详细的格式。这也是一个当你要产生并输出多种格式的字符串时要使用的接口。customer类就是这种情况,用户将希望产生一个报表,这个报表包含了已经表格化了的用户名和去年的收入。IFormattable.ToString()方法正合你意,它可以让用户格式化输出你的类型信息。这个方法原型的参数上一包含一个格式化字符串和一个格式化引擎:
string System.IFormattable.ToString( string format,
IFormatProvider formatProvider )
你可以为你设计的类型指定要使用的格式字符串。你也可以为你的格式字符串指定关键字符。在这个customer的例子中,你可以完全可以用n来表示名字,r表示收入以及p来表示电话。这样一来,你的用户就可以随意的组合指定信息,而你则须要为你的类型提供下面这个版本的的IFormattable.ToString():
#region IFormattable Members
// supported formats:
// substitute n for name.
// substitute r for revenue
// substitute p for contact phone.
// Combos are supported: nr, np, npr, etc
// "G" is general.
string System.IFormattable.ToString( string format,
IFormatProvider formatProvider )
{
if ( formatProvider != null )
{
ICustomFormatter fmt = formatProvider.GetFormat(
this.GetType( ) )
as ICustomFormatter;
if ( fmt != null )
return fmt.Format( format, this, formatProvider );
}
switch ( format )
{
case "r":
return _revenue.ToString( );
case "p":
return _contactPhone;
case "nr":
return string.Format( "{0,20}, {1,10:C}",
_name, _revenue );
case "np":
return string.Format( "{0,20}, {1,15}",
_name, _contactPhone );
case "pr":
return string.Format( "{0,15}, {1,10:C}",
_contactPhone, _revenue );
case "pn":
return string.Format( "{0,15}, {1,20}",
_contactPhone, _name );
case "rn":
return string.Format( "{0,10:C}, {1,20}",
_revenue, _name );
case "rp":
return string.Format( "{0,10:C}, {1,20}",
_revenue, _contactPhone );
case "nrp":
return string.Format( "{0,20}, {1,10:C}, {2,15}",
_name, _revenue, _contactPhone );
case "npr":
return string.Format( "{0,20}, {1,15}, {2,10:C}",
_name, _contactPhone, _revenue );
case "pnr":
return string.Format( "{0,15}, {1,20}, {2,10:C}",
_contactPhone, _name, _revenue );
case "prn":
return string.Format( "{0,15}, {1,10:C}, {2,15}",
_contactPhone, _revenue, _name );
case "rpn":
return string.Format( "{0,10:C}, {1,15}, {2,20}",
_revenue, _contactPhone, _name );
case "rnp":
return string.Format( "{0,10:C}, {1,20}, {2,15}",
_revenue, _name, _contactPhone );
case "n":
case "G":
default:
return _name;
}
}
#endregion
(译注:上面的做法显然不合理,要是我的对象有10个成员,这样的组合是会让人疯掉的。推荐使用正则表达式来完成这样的工作,正则表达式在处理文字时的表现还是很出色的。)
添加了这样的函数后,你就让用户具有了可以这样指定customer数据的能力:
IFormattable c1 = new Customer();
Console.WriteLine( "Customer record: {0}",
c1.ToString( "nrp", null ) );
任何对IFormattable.ToString()的实现都要指明类型,但不管你在什么时候实现IFormattation接口,你都要注意处理大小写。首先,你必须支持能用格式化字符:“G”。其次,你必须支持两个空格式化字符:""和null。当你重载Object.ToString()这个方法时,这三个格式化字符应该返回同样的字符串。.Net的FCL经常用null来调用IFormattable.ToString()方法,来取代对Object.ToString()的调用,但在少数地方使用格式符"G"来格式化字符串,从而区别通用的格式。如果你添加了对IFormattable接口的支持,并不再支持标准的格式化,你将会破坏FCL里的字符串的自动(隐式)转换。
IFormattable.ToString()的第二个参数是一个实现了IFormatProvider接口的对象。这个对象为用户提供了一些你没有预先设置的格式化选项(译注:简单一点,就是你可以只实现你自己的格式化选项,其它的默认由它来完成)。如果你查看一下前面IFormattable.ToString()的实现,你就会毫不犹豫的拿出不计其数的,任何你喜欢的格式化选项,而这些都是的格式化中所没有的。支持人们容易阅读的输出是很自然的事,但不管你支持多少种格式,你的用户总有一天会想要你预先没想到的格式。这就为什么这个方法的前几行要检察实现了IFormatProvider的对象,并把ICustomFormatter的工作委托给它了。
让我们把(讨论的)焦点从类的作者转移到类的使用者上来。你发现你想要的格式化不被支持。例如,你有一个一组客户,他们的名字有的大于20个字符,并且你想修改格式化选项,让它支持50个字符长的客户名。这就是为什么IFormatProvider接口要存在。你可以设计一个实现了IFormatProvider的类,并且让它同时实现ICustomFormatter接口用于格式化输出。IFormatProvider接口定义了一个方法:GetFormat()。这个方法返回一个实现了ICustomFormatter接口的对象。由ICustomFormatter接口的指定方法来完成实际的格式化工作。下面这一对(接口)实现了对输出的修改,让它可以支持50个字符长的用户名:
// Example IFormatProvider:
public class CustomFormatter : IFormatProvider
{
#region IFormatProvider Members
// IFormatProvider contains one method.
// This method returns an object that
// formats using the requested interface.
// Typically, only the ICustomFormatter
// is implemented
public object GetFormat( Type formatType )
{
if ( formatType == typeof( ICustomFormatter ))
return new CustomerFormatProvider( );
return null;
}
#endregion
// Nested class to provide the
// custom formatting for the Customer class.
private class CustomerFormatProvider : ICustomFormatter
{
#region ICustomFormatter Members
public string Format( string format, object arg,
IFormatProvider formatProvider )
{
Customer c = arg as Customer;
if ( c == null )
return arg.ToString( );
return string.Format( "{0,50}, {1,15}, {2,10:C}",
c.Name, c.ContactPhone, c.Revenue );
}
#endregion
}
}
GetFormat()方法取得一个实现了ICustomFormatter接口的对象。而ICustomFormatter.Format()方法,则根据用户需求负责实际的格式化输出工作。这个方法把对象转换成格式化的字符串。你可以为ICustomFormatter.Format()定义格式化字符串,因此你可以按常规指定多重格式。FormatProvider就是一个由GetFormat()方法取得的IFormatProvider对象。
为了满足用户的格式化要求,你必须用IFormatProvider对象明确的调用string.Format()方法:
Console.WriteLine( string.Format( new CustomFormatter(), "", c1 ));
你可以设计一个类,让它实现IFormatProvider和ICustomFormatter接口,再实现或者不实现IFormattable 接口。因此,即使这个类的作者没有提供合理的ToStrying行为,你可以自己来完成。当然,从类的外面来实现,你只能访问公共属性成数据来取得字符串。实现两个接口,IFormatProvider 和 IcustomFormatter, 只做一些文字输出,并不需要很多工作。但在.Net框架里,你所实现的指定的文字输出在哪里都可以得到很好的支持。
所以,再回到类的作者上来。重写Object.ToString(),为你的类提供一些说明是件很简单的事。你每次都应该为你的类型提供这样的支持。而且这应该是对你的类型最显而易见的,最常用的说明。在一些极端情况下,你的格式化不能支持一些过于灵活的输出时,你应该借用IFormattable接口的优势。它为你的类型进行自定义格式化输出提供了标准方法。如果你放弃这些,你的用户将失去用于实现自定义格式化的工具。这些解决办法须要写更多的代码,并且因为你的用户是在类的外面的,所以他们无法检查类的里面的状态。
最后,大家注意到你的类型的信息,他们会明白输出的文字。尽可能以简单的方式的提供这样的信息吧:为你的所有类型重写ToString()方法。
#37
Agreed!Bill.
#38
还是不太同意
我坚持
仅仅在需要的时候重写ToString()方法
#39
条款1:使用属性代替可访问的数据成员
条款2:运行时常量(readonly)优于编译时常量(const)
条款3:操作符is或as优于强制转型
条款4:使用Conditional特性代替#if条件编译
条款5:总是提供ToString()方法
条款6:明辨值类型和引用类型的使用场合
条款7:将值类型尽可能实现为具有常量性和原子性的类型
条款8:确保0为值类型的有效状态
条款9:理解几个相等判断之间的关系
条款10:理解GetHashCode()方法的缺陷
条款11:优先采用foreach循环语句
条款12:变量初始化器优于赋值语句
条款13:使用静态构造器初始化静态类成员
条款14:利用构造器链
条款15:利用using和try/finally语句来清理资源
条款16:尽量减少内存垃圾
条款17:尽量减少装箱与拆箱
条款18:实现标准Dispose模式
条款19:定义并实现接口优于继承类型
条款20:明辨接口实现和虚方法重写
条款21:使用委托表达回调
条款22:使用事件定义外发接口
条款23:避免返回内部类对象的引用
条款24:声明式编程优于命令式编程
条款25:尽可能将类型实现为可序列化的类型
条款26:使用IComparable和IComparer接口实现排序关系
条款27:避免ICloneable接口
条款28:避免强制转换操作符
条款29:只有当新版基类导致问题时才考虑使用new修饰符
条款30:尽可能实现CLS兼容的程序集
条款31:尽可能实现短小简洁的函数
条款32:尽可能实现小尺寸、高内聚的程序集
条款33:限制类型的可见性
条款34:创建大粒度的Web API
条款35:重写优于事件处理器
条款36:合理使用.NET运行时诊断
条款37:使用标准配置机制
条款38:定制和支持数据绑定
条款39:使用.NET验证
条款40:根据需要选用恰当的集合
条款41:DataSet优于自定义结构
条款42:利用特性简化反射
条款43:避免过度使用反射
条款44:为应用程序创建特定的异常类
条款45:优先选择强异常安全保证
条款46:最小化互操作
条款47:优先选择安全代码
条款48:掌握相关工具与资源
条款49:为C# 2.0做准备
条款50:了解ECMA标准
条款2:运行时常量(readonly)优于编译时常量(const)
条款3:操作符is或as优于强制转型
条款4:使用Conditional特性代替#if条件编译
条款5:总是提供ToString()方法
条款6:明辨值类型和引用类型的使用场合
条款7:将值类型尽可能实现为具有常量性和原子性的类型
条款8:确保0为值类型的有效状态
条款9:理解几个相等判断之间的关系
条款10:理解GetHashCode()方法的缺陷
条款11:优先采用foreach循环语句
条款12:变量初始化器优于赋值语句
条款13:使用静态构造器初始化静态类成员
条款14:利用构造器链
条款15:利用using和try/finally语句来清理资源
条款16:尽量减少内存垃圾
条款17:尽量减少装箱与拆箱
条款18:实现标准Dispose模式
条款19:定义并实现接口优于继承类型
条款20:明辨接口实现和虚方法重写
条款21:使用委托表达回调
条款22:使用事件定义外发接口
条款23:避免返回内部类对象的引用
条款24:声明式编程优于命令式编程
条款25:尽可能将类型实现为可序列化的类型
条款26:使用IComparable和IComparer接口实现排序关系
条款27:避免ICloneable接口
条款28:避免强制转换操作符
条款29:只有当新版基类导致问题时才考虑使用new修饰符
条款30:尽可能实现CLS兼容的程序集
条款31:尽可能实现短小简洁的函数
条款32:尽可能实现小尺寸、高内聚的程序集
条款33:限制类型的可见性
条款34:创建大粒度的Web API
条款35:重写优于事件处理器
条款36:合理使用.NET运行时诊断
条款37:使用标准配置机制
条款38:定制和支持数据绑定
条款39:使用.NET验证
条款40:根据需要选用恰当的集合
条款41:DataSet优于自定义结构
条款42:利用特性简化反射
条款43:避免过度使用反射
条款44:为应用程序创建特定的异常类
条款45:优先选择强异常安全保证
条款46:最小化互操作
条款47:优先选择安全代码
条款48:掌握相关工具与资源
条款49:为C# 2.0做准备
条款50:了解ECMA标准
#40
使用数据库时,存储过程参数,尽量不要拼接字符串。
数据库要建立索引、使用事务。
ASP.NET合理利用母版页和缓存。
提取字符串注意正则表达式的优化,提高准确性来减少迭代。
算术表达式要多用小括号。
private bool test = false;if(test){;}
结构简单时使用三目运算符。
灵活使用switch。
数据库要建立索引、使用事务。
ASP.NET合理利用母版页和缓存。
提取字符串注意正则表达式的优化,提高准确性来减少迭代。
算术表达式要多用小括号。
private bool test = false;if(test){;}
结构简单时使用三目运算符。
灵活使用switch。
#41
大家都牛啊!
哈哈,顶一下1
哈哈,顶一下1
#42
尽量使用托管代码。
平时写的代码要OOP,然后封装成自己的类库,提高日后开发效率。
多用组合,少用继承。
字符串合理使用Trim()。
实现文件复制时,尽量减少对磁盘读写次数。
平时写的代码要OOP,然后封装成自己的类库,提高日后开发效率。
多用组合,少用继承。
字符串合理使用Trim()。
实现文件复制时,尽量减少对磁盘读写次数。
#43
正是因为DataTable的强大所以才不推荐使用它(不是不能)
考虑下面的代码:
DataTable GetEmployee1() {
return table;
}
Ilist<EmployeeInfo> GetEmployee2() {
return list;
}
void InitInterfaceUsingDataTable() {
DataRow row = GetEmployee1().rows[0];
this.txName = row["EmployeeName"]; // 你确定字段名是EmployeeName吗?
}
void InitInterfaveUsingList() {
EmployeeInfo> employee = GetEmployee2()[0];
this.txName = list.EmployeeName; // 这样写代码很舒服
}
// 再考虑下下下面的情况
// 某天,老板对你说:“嘿,去把EmployeeName改成EmployeeFirstName”
#44
Great!
#45
学习了!
#46
此贴会火... 留名
#47
同意,不过加一点:
使用非托管代码写保密性的算法或很有价值的算法。
#48
楼主可以对那50条分别开贴探讨指导下
#49
如果托管代码用到了非托管资源,最好使用Dispose模式,并且一定要手写代码清理非托管资源
#50
Thread..
#1
。。。
#2
刚给control写了个扩展方法,按回车发送tab键的 ^_^
public static class ControlExtensions
{
public static void SendTabKey(this Control control, Keys key)
{
if (key == Keys.Enter)
SendKeys.Send("{TAB}");
}
}
#3
占座
#4
遍歷control
private void PanelClear(Control c)
{
foreach (Control cc in c.Controls)
{
if (cc.GetType() != typeof(Panel))
{
PanelClear(cc);
}
else
{
((Panel)cc).Visible = false;
}
}
}
#5
1)对所有类都重写ToString()方法,这样在调试,绑定中都非常有用。
2)使用Enum代替奇迹数
先说两点。想起来再加。
2)使用Enum代替奇迹数
先说两点。想起来再加。
#6
找出是否存在某個窗體FORM
for (int j = 0; j < Application.OpenForms.Count; j++)
{
if (Application.OpenForms[j].Name.Equals("FNO31000"))
{
fno3100 = true;
}
}
If (fno3100 = true)
FNO31000 fno = (FNO31000)Application.OpenForms["FNO31000"]
#7
插队
#8
lz写的第4点,用String.Format() 如何?
String.Format("{0}{1}{2}{3}", str0, str1, str2, str3);
#9
留个名,学习
#10
將datagridview的某個checkbox不顯示
public void chang_COLOR(int i, string str)//將顯示為N者不顯示選取方塊
{
dataGridView1.Rows[i].Cells[str].ReadOnly = true;
DataGridViewCell cell = new DataGridViewTextBoxCell();
cell.Style.BackColor = Color.Wheat;
//cell.ReadOnly = true;
cell.Value = "N";
cell.Style.BackColor = Color.White;
dataGridView1.Rows[i].Cells[str] = cell;
dataGridView1.Rows[i].Cells[str].Style.ForeColor = Color.White;
dataGridView1.Rows[i].Cells[str].Style.SelectionBackColor = Color.White;
dataGridView1.Rows[i].Cells[str].Style.SelectionForeColor = Color.White;
}
#11
打開某個路徑下的程序
Process p = new Process();就贴这么多把
p.StartInfo.FileName = "cmd.exe"; //设定程序名
p.StartInfo.UseShellExecute = false; //关 ?Shell的使用
p.StartInfo.RedirectStandardInput = true; //重定向标 ã输 ¤J
p.StartInfo.RedirectStandardOutput = true; //重定向标 ã输 ¥X
p.StartInfo.RedirectStandardError = true; //重定向错 ?输 ¥X
p.StartInfo.CreateNoWindow = true; //设置不显 ¥Ü窗口
p.StartInfo.WorkingDirectory = @"E:\";
p.Start(); //启 ?
p.StandardInput.WriteLine("新增文字文件.bat");
p.StandardInput.WriteLine("exit");
#12
再来一些
自认为比较高级的:
1. 字符串留用技术
字符串留用技术用来处理大量的字符串,而这些字符串中又会有许多重复的字符,例如:
"str1", "str2", ... , "str100" 共10,000个这样的字符,毫无疑问,其实就99个字符
这种情况可以使用到字符串留用技术,会提到性能
2. 数组永远是0基的
3. 使用多线程或异步操作的时候使用线程池的QueueUserWorkItem()方法将需要执行的任务排队,而不是手动去Start一个线程
1. 字符串留用技术
字符串留用技术用来处理大量的字符串,而这些字符串中又会有许多重复的字符,例如:
"str1", "str2", ... , "str100" 共10,000个这样的字符,毫无疑问,其实就99个字符
这种情况可以使用到字符串留用技术,会提到性能
2. 数组永远是0基的
3. 使用多线程或异步操作的时候使用线程池的QueueUserWorkItem()方法将需要执行的任务排队,而不是手动去Start一个线程
#13
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
public delegate bool DelegateTest(object obj1, object obj2);
class Class1
{
static void Main()
{
Employee[] Employees =
{
new Employee("huguo",1000000),
new Employee("lili",20000),
new Employee("lulu",30000),
new Employee("xixi",50000),
new Employee("jianjian",10000),
new Employee("yoyo",9000)
};
//委托DelegateTest代理的方法是Greate
DelegateTest MyTest = new DelegateTest(Employee.Greate);
Sorter MySort = new Sorter();
//冒泡算法中第一个参数是对应Employees数组信息,第二个参数是委托
MySort.Sort(Employees, MyTest);
for (int m = 0; m < Employees.Length; m++)
{
Console.WriteLine(Employees[m].ToString());
}
}
}
class Employee
{
public string Name;
public int Salary;
public Employee(string Name, int Salary)
{
this.Name = Name;
this.Salary = Salary;
}
//用override重写string方法
public override string ToString()
{
return string.Format(Name + ",{0:C},", Salary);
}
//定义一个方法,如果obj2传过来的 Salary大于obj1就返回true;
public static bool Greate(object obj1, object obj2)
{
Employee Employee1 = (Employee)obj1;
Employee Employee2 = (Employee)obj2;
return (Employee2.Salary > Employee1.Salary) ? true : false;
}
}
class Sorter
{
public void Sort(object[] ArrayObj, DelegateTest Test)
{
//下面就是冒泡算法啦
for (int i = 0; i < ArrayObj.Length; i++)
{
for (int j = i + 1; j < ArrayObj.Length; j++)
{
if (Test(ArrayObj[j], ArrayObj[i]))
{
object Temp = ArrayObj[i];
ArrayObj[i] = ArrayObj[j];
ArrayObj[j] = Temp;
}
}
}
}
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/07/25/4380283.aspx
#14
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
CreateNum();
}
}
//在从1到20间随机生成6个互不相同的整数。
public void CreateNum()
{
ArrayList MyArray = new ArrayList();
Random random = new Random();
string str = null;
//循环的次数
int Nums = 6;
while (Nums > 0)
{
int i = random.Next(1, 9);
if (!MyArray.Contains(i))
{
if (MyArray.Count < 6)
{
MyArray.Add(i);
}
}
Nums -= 1;
}
for (int j = 0; j <= MyArray.Count - 1; j++)
{
str += MyArray[j].ToString();
}
Response.Write(str);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/05/09/4164277.aspx
#15
//方法1
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ReplaceStr();
}
}
public void ReplaceStr()
{
ArrayList MyArray = new ArrayList();
MyArray.Add("123");
MyArray.Add("aaa");
if (MyArray.Contains("aaa"))
{
MyArray.Remove("aaa");
MyArray.Add("bbb");
}
for (int i = 0; i <= MyArray.Count - 1; i++)
{
Response.Write(MyArray[i].ToString());
}
}
//方法2
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ReplaceStr();
}
}
public void ReplaceStr()
{
string [] tm = new string[] { "123", "aaa" };
for (int i = 0; i < tm.Length; i++)
{
if (tm[i].ToString() == "aaa")
{
tm[i]=tm[i].Replace("aaa", "bbb");
}
}
for (int i = 0; i <= tm.Length - 1; i++)
{
Response.Write(tm[i].ToString());
}
}
//方法3
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string[] tm = new string[] { "123", "aaa" };
string Array=ReplaceValue(tm, "aaa", "bbb", ",");
Response.Write(Array);
}
}
public static string ReplaceValue(string[] item, string oldSv, string newSv, string separator)
{
if (item == null) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string s in item)
{
if (s == oldSv)
{
sb.Append(newSv);
sb.Append(separator);
}
else
{
sb.Append(s);
sb.Append(separator);
}
}
string returnstr = sb.ToString();
returnstr = (returnstr.EndsWith(separator)) ? returnstr.Substring(0, returnstr.Length - 1) : returnstr;
return returnstr;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/05/10/4164995.aspx
#16
效率一定没有直接赋值高,因为你的代码涉及到方法调用的开销,而且有异常。
不过,很多情况下,这个方法非常直观,大大的推荐使用。
#17
#18
学习了,先
#19
private static void PrepareCommand(MySqlConnection con,MySqlCommand mycmd,string cmdText,MySqlParameter[] cmdParams,CommandType cmdType)
{
con.Open();
mycmd.Connection = con;
mycmd.CommandText = cmdText;
mycmd.CommandType = cmdType;
if (cmdParams != null)
{
foreach (MySqlParameter param in cmdParams)
{
//if((param.Direction==ParameterDirection.InputOutput || param.Direction==ParameterDirection.Input) && (param.Value==null))
//{
// param.Value = DBNull.Value;
mycmd.Parameters.Add(param);
//}
}
}
}
#20
强贴留名。
#21
这算小技巧吧。
#22
楼上用MySql?
本人很喜欢MySql!
#23
如果实现了IDisposable的对象在访问完成后要进行关闭,则在try{...}finally{...//关闭代码},或直接调用using(...){...}。
#24
为什么用SqlDataReader而不用DataSet?
SqlDataReader持久占连接。
而且DataSet对VS控件的兼容性更强一些。
SqlDataReader持久占连接。
而且DataSet对VS控件的兼容性更强一些。
#25
学啊 不学怎么进步
#26
楼主说的不是Effective C# 上的
#27
对于第一点,有待考究。哈哈
#28
在写公共类库,使用catch时,最好不要catch(Exception e){throw e;}而使用catch{throw;},同时如果使用catch捕捉异常,最好使用catch(最具体的Exception e){...}catch(最具体的Exception e){...}...一直到所有确认的错误都能检查到 ;而不要使用catch(基类Exception e){...}
#29
推荐使用using(){}
去写实现了IDisposable的对象
非常漂亮!
#30
学习
#31
//尽量不用
string str="";
//而是
string str=string.Empty;
#32
DataSet过于强大
但是,强大是要付出代价的,哈哈
其实,DataTable内部就是用了SqlDataReader( 本人98%肯定)
#33
看不太懂。。。 插队插队
#34
一般情况下,这个问题基本上不用考虑。
但是上升到公共类库,就需要考虑语言的互操作性
也就是CLR的兼容性
如果我没有记错的话:
Catch(Exception) 只捕捉符合公共语言运行库的异常
Catch{} 则可以捕捉所有类型的异常
#35
释放连接后,DataTable是能够使用的啊,难道从头迭代到末尾了?
#36
Effective C# 原则5:始终提供ToString()(部分翻译)
Always Provide ToString()
在.Net世界里,用得最多的方法之一就是System.Object.ToStrying()了。你应该为你所有的客户写一个“通情达理”的类(译注:这里是指这个类应该对用户友好)。要么,你就迫使所用类的用户,去使用类的属性并添加一些合理的易读的说明。这个以字符串形式存在,关于你设计的类的说明,可以很容易的向你的用户显示一些关于对象的信息到:Windows Form里,Web Form里,控制台输出。这些字符说明可以用于调试。你写的任何一种类型,都应该合理的重写这个方法。当你设计更多的复杂的类型时,你应该实现应变能力更强的IFormattable.ToString(). 承认这个:如果你不重写(override)这个常规的方法,或者只是写一个很糟糕的,你的客户将不得不为你修正它。
System.Object版的ToString()方法只返回类型的名字。这并没有太多有用的信息:“Rect”,“Point”,“Size”并不会如你所想的那样显示给你的用户。但那只是在你没有为你的类重写ToString()方法时得到的。你只用为你的类写一次,但你的客户却会使用很多次。当你设计一个类时,多添加一点小小的工作,就可以在你或者是其他人每次使用时得到回报。
(译注:废话!)
======================
这一原则就不翻译了,看的有点郁闷。就是ToString()的几个重写版本。以及一些格式化输出。我觉得本书不应该讨论这些入门级的内容,所以只是读了一遍,就没有全部翻译。
大家知道要重写它就行了,最好是提供几个重载版本。回头有时间再翻译这一原则的其它内容。
给一点个人建议,一般不会在一个类的ToString上提供很多的说明,给一个名字就已经足够了,然后加一个SDK帮助。更多时候,在后面添加成员类的说明。我就在一个第三方库的ToString上看到很严谨的结构,都是在类名后面,添加一些内容和重要属性的说明。
=========================================补译:
让我们来考虑一个简单的需求:重写System.Object.ToString()方法。你所设计的每一个类型都应该重写ToString()方法,用来为你的类型提供一些最常用的文字说明。考虑这个Customer类以及它的三个成员(fields)(译注:一般情况,类里的fields译为成员,这是面向对象设计时的概念,而在与数据库相关的地方,则是指字段):
public class Customer
{
private string _name;
private decimal _revenue;
private string _contactPhone;
}
默认继承自System.Object的ToString()方法会返回"Customer"。这对每个人都不会有太大的帮助。就算ToString()只是为了在调试时使用,也应该更灵活(sophisticated)一些。你重写的ToString()方法应该返回文字说明,更像是你的用户在使用这个类一样。在Customer例子中,这应该是名字:
public override string ToString()
{
return _name;
}
如果你不遵守这一原则里的其它意见,就按照上面的方法为你所定义的所有类型重写该方法。它会直接为每个人省下时间。
当你负责任的为Object.ToString()方法实现了重写时,这个类的对象可以更容易的被添加到Windows Form里,Web Form里,或者打印输出。 .NET的FCL使用重载的Object.ToString()在控件中显示对象:组合框,列表框,文本框,以及其它一些控件。如果你一个Windows Form或者Web Form里添加一个Customer对象的链表,你将会得到它们的名字(以文本)显示出来(译注:而不是每个对象都是同样的类型名)。
Syste.Console.WriteLine()和System.String.Formate()在内部(实现的方法)是一样的。任何时候,.Net的FCL想取得一个customer的字符串说明时,你的customer类型会提供一个客户的名字。一个只有三行的简单函数,完成了所有的基本需求。
这是一个简单的方法,ToString()还可以以文字(输出的方法)满足很多用户自定义类型的需求。但有些时候,你的要求可能会更多。前面的customer类型有三个成员:名字,收入和联系电话。对System.Object.ToString()(译注:原文这里有误,掉了Object)的重写只使用了_name。你可以通过实现IFormattable(这个接口)来弥补这个不足。这是一个当你需要对外输出格式化文本时使用的接口。IFormattable包含一个重载版的ToString()方法,使用这个方法,你可以为你的类型信息指定详细的格式。这也是一个当你要产生并输出多种格式的字符串时要使用的接口。customer类就是这种情况,用户将希望产生一个报表,这个报表包含了已经表格化了的用户名和去年的收入。IFormattable.ToString()方法正合你意,它可以让用户格式化输出你的类型信息。这个方法原型的参数上一包含一个格式化字符串和一个格式化引擎:
string System.IFormattable.ToString( string format,
IFormatProvider formatProvider )
你可以为你设计的类型指定要使用的格式字符串。你也可以为你的格式字符串指定关键字符。在这个customer的例子中,你可以完全可以用n来表示名字,r表示收入以及p来表示电话。这样一来,你的用户就可以随意的组合指定信息,而你则须要为你的类型提供下面这个版本的的IFormattable.ToString():
#region IFormattable Members
// supported formats:
// substitute n for name.
// substitute r for revenue
// substitute p for contact phone.
// Combos are supported: nr, np, npr, etc
// "G" is general.
string System.IFormattable.ToString( string format,
IFormatProvider formatProvider )
{
if ( formatProvider != null )
{
ICustomFormatter fmt = formatProvider.GetFormat(
this.GetType( ) )
as ICustomFormatter;
if ( fmt != null )
return fmt.Format( format, this, formatProvider );
}
switch ( format )
{
case "r":
return _revenue.ToString( );
case "p":
return _contactPhone;
case "nr":
return string.Format( "{0,20}, {1,10:C}",
_name, _revenue );
case "np":
return string.Format( "{0,20}, {1,15}",
_name, _contactPhone );
case "pr":
return string.Format( "{0,15}, {1,10:C}",
_contactPhone, _revenue );
case "pn":
return string.Format( "{0,15}, {1,20}",
_contactPhone, _name );
case "rn":
return string.Format( "{0,10:C}, {1,20}",
_revenue, _name );
case "rp":
return string.Format( "{0,10:C}, {1,20}",
_revenue, _contactPhone );
case "nrp":
return string.Format( "{0,20}, {1,10:C}, {2,15}",
_name, _revenue, _contactPhone );
case "npr":
return string.Format( "{0,20}, {1,15}, {2,10:C}",
_name, _contactPhone, _revenue );
case "pnr":
return string.Format( "{0,15}, {1,20}, {2,10:C}",
_contactPhone, _name, _revenue );
case "prn":
return string.Format( "{0,15}, {1,10:C}, {2,15}",
_contactPhone, _revenue, _name );
case "rpn":
return string.Format( "{0,10:C}, {1,15}, {2,20}",
_revenue, _contactPhone, _name );
case "rnp":
return string.Format( "{0,10:C}, {1,20}, {2,15}",
_revenue, _name, _contactPhone );
case "n":
case "G":
default:
return _name;
}
}
#endregion
(译注:上面的做法显然不合理,要是我的对象有10个成员,这样的组合是会让人疯掉的。推荐使用正则表达式来完成这样的工作,正则表达式在处理文字时的表现还是很出色的。)
添加了这样的函数后,你就让用户具有了可以这样指定customer数据的能力:
IFormattable c1 = new Customer();
Console.WriteLine( "Customer record: {0}",
c1.ToString( "nrp", null ) );
任何对IFormattable.ToString()的实现都要指明类型,但不管你在什么时候实现IFormattation接口,你都要注意处理大小写。首先,你必须支持能用格式化字符:“G”。其次,你必须支持两个空格式化字符:""和null。当你重载Object.ToString()这个方法时,这三个格式化字符应该返回同样的字符串。.Net的FCL经常用null来调用IFormattable.ToString()方法,来取代对Object.ToString()的调用,但在少数地方使用格式符"G"来格式化字符串,从而区别通用的格式。如果你添加了对IFormattable接口的支持,并不再支持标准的格式化,你将会破坏FCL里的字符串的自动(隐式)转换。
IFormattable.ToString()的第二个参数是一个实现了IFormatProvider接口的对象。这个对象为用户提供了一些你没有预先设置的格式化选项(译注:简单一点,就是你可以只实现你自己的格式化选项,其它的默认由它来完成)。如果你查看一下前面IFormattable.ToString()的实现,你就会毫不犹豫的拿出不计其数的,任何你喜欢的格式化选项,而这些都是的格式化中所没有的。支持人们容易阅读的输出是很自然的事,但不管你支持多少种格式,你的用户总有一天会想要你预先没想到的格式。这就为什么这个方法的前几行要检察实现了IFormatProvider的对象,并把ICustomFormatter的工作委托给它了。
让我们把(讨论的)焦点从类的作者转移到类的使用者上来。你发现你想要的格式化不被支持。例如,你有一个一组客户,他们的名字有的大于20个字符,并且你想修改格式化选项,让它支持50个字符长的客户名。这就是为什么IFormatProvider接口要存在。你可以设计一个实现了IFormatProvider的类,并且让它同时实现ICustomFormatter接口用于格式化输出。IFormatProvider接口定义了一个方法:GetFormat()。这个方法返回一个实现了ICustomFormatter接口的对象。由ICustomFormatter接口的指定方法来完成实际的格式化工作。下面这一对(接口)实现了对输出的修改,让它可以支持50个字符长的用户名:
// Example IFormatProvider:
public class CustomFormatter : IFormatProvider
{
#region IFormatProvider Members
// IFormatProvider contains one method.
// This method returns an object that
// formats using the requested interface.
// Typically, only the ICustomFormatter
// is implemented
public object GetFormat( Type formatType )
{
if ( formatType == typeof( ICustomFormatter ))
return new CustomerFormatProvider( );
return null;
}
#endregion
// Nested class to provide the
// custom formatting for the Customer class.
private class CustomerFormatProvider : ICustomFormatter
{
#region ICustomFormatter Members
public string Format( string format, object arg,
IFormatProvider formatProvider )
{
Customer c = arg as Customer;
if ( c == null )
return arg.ToString( );
return string.Format( "{0,50}, {1,15}, {2,10:C}",
c.Name, c.ContactPhone, c.Revenue );
}
#endregion
}
}
GetFormat()方法取得一个实现了ICustomFormatter接口的对象。而ICustomFormatter.Format()方法,则根据用户需求负责实际的格式化输出工作。这个方法把对象转换成格式化的字符串。你可以为ICustomFormatter.Format()定义格式化字符串,因此你可以按常规指定多重格式。FormatProvider就是一个由GetFormat()方法取得的IFormatProvider对象。
为了满足用户的格式化要求,你必须用IFormatProvider对象明确的调用string.Format()方法:
Console.WriteLine( string.Format( new CustomFormatter(), "", c1 ));
你可以设计一个类,让它实现IFormatProvider和ICustomFormatter接口,再实现或者不实现IFormattable 接口。因此,即使这个类的作者没有提供合理的ToStrying行为,你可以自己来完成。当然,从类的外面来实现,你只能访问公共属性成数据来取得字符串。实现两个接口,IFormatProvider 和 IcustomFormatter, 只做一些文字输出,并不需要很多工作。但在.Net框架里,你所实现的指定的文字输出在哪里都可以得到很好的支持。
所以,再回到类的作者上来。重写Object.ToString(),为你的类提供一些说明是件很简单的事。你每次都应该为你的类型提供这样的支持。而且这应该是对你的类型最显而易见的,最常用的说明。在一些极端情况下,你的格式化不能支持一些过于灵活的输出时,你应该借用IFormattable接口的优势。它为你的类型进行自定义格式化输出提供了标准方法。如果你放弃这些,你的用户将失去用于实现自定义格式化的工具。这些解决办法须要写更多的代码,并且因为你的用户是在类的外面的,所以他们无法检查类的里面的状态。
最后,大家注意到你的类型的信息,他们会明白输出的文字。尽可能以简单的方式的提供这样的信息吧:为你的所有类型重写ToString()方法。
#37
Agreed!Bill.
#38
还是不太同意
我坚持
仅仅在需要的时候重写ToString()方法
#39
条款1:使用属性代替可访问的数据成员
条款2:运行时常量(readonly)优于编译时常量(const)
条款3:操作符is或as优于强制转型
条款4:使用Conditional特性代替#if条件编译
条款5:总是提供ToString()方法
条款6:明辨值类型和引用类型的使用场合
条款7:将值类型尽可能实现为具有常量性和原子性的类型
条款8:确保0为值类型的有效状态
条款9:理解几个相等判断之间的关系
条款10:理解GetHashCode()方法的缺陷
条款11:优先采用foreach循环语句
条款12:变量初始化器优于赋值语句
条款13:使用静态构造器初始化静态类成员
条款14:利用构造器链
条款15:利用using和try/finally语句来清理资源
条款16:尽量减少内存垃圾
条款17:尽量减少装箱与拆箱
条款18:实现标准Dispose模式
条款19:定义并实现接口优于继承类型
条款20:明辨接口实现和虚方法重写
条款21:使用委托表达回调
条款22:使用事件定义外发接口
条款23:避免返回内部类对象的引用
条款24:声明式编程优于命令式编程
条款25:尽可能将类型实现为可序列化的类型
条款26:使用IComparable和IComparer接口实现排序关系
条款27:避免ICloneable接口
条款28:避免强制转换操作符
条款29:只有当新版基类导致问题时才考虑使用new修饰符
条款30:尽可能实现CLS兼容的程序集
条款31:尽可能实现短小简洁的函数
条款32:尽可能实现小尺寸、高内聚的程序集
条款33:限制类型的可见性
条款34:创建大粒度的Web API
条款35:重写优于事件处理器
条款36:合理使用.NET运行时诊断
条款37:使用标准配置机制
条款38:定制和支持数据绑定
条款39:使用.NET验证
条款40:根据需要选用恰当的集合
条款41:DataSet优于自定义结构
条款42:利用特性简化反射
条款43:避免过度使用反射
条款44:为应用程序创建特定的异常类
条款45:优先选择强异常安全保证
条款46:最小化互操作
条款47:优先选择安全代码
条款48:掌握相关工具与资源
条款49:为C# 2.0做准备
条款50:了解ECMA标准
条款2:运行时常量(readonly)优于编译时常量(const)
条款3:操作符is或as优于强制转型
条款4:使用Conditional特性代替#if条件编译
条款5:总是提供ToString()方法
条款6:明辨值类型和引用类型的使用场合
条款7:将值类型尽可能实现为具有常量性和原子性的类型
条款8:确保0为值类型的有效状态
条款9:理解几个相等判断之间的关系
条款10:理解GetHashCode()方法的缺陷
条款11:优先采用foreach循环语句
条款12:变量初始化器优于赋值语句
条款13:使用静态构造器初始化静态类成员
条款14:利用构造器链
条款15:利用using和try/finally语句来清理资源
条款16:尽量减少内存垃圾
条款17:尽量减少装箱与拆箱
条款18:实现标准Dispose模式
条款19:定义并实现接口优于继承类型
条款20:明辨接口实现和虚方法重写
条款21:使用委托表达回调
条款22:使用事件定义外发接口
条款23:避免返回内部类对象的引用
条款24:声明式编程优于命令式编程
条款25:尽可能将类型实现为可序列化的类型
条款26:使用IComparable和IComparer接口实现排序关系
条款27:避免ICloneable接口
条款28:避免强制转换操作符
条款29:只有当新版基类导致问题时才考虑使用new修饰符
条款30:尽可能实现CLS兼容的程序集
条款31:尽可能实现短小简洁的函数
条款32:尽可能实现小尺寸、高内聚的程序集
条款33:限制类型的可见性
条款34:创建大粒度的Web API
条款35:重写优于事件处理器
条款36:合理使用.NET运行时诊断
条款37:使用标准配置机制
条款38:定制和支持数据绑定
条款39:使用.NET验证
条款40:根据需要选用恰当的集合
条款41:DataSet优于自定义结构
条款42:利用特性简化反射
条款43:避免过度使用反射
条款44:为应用程序创建特定的异常类
条款45:优先选择强异常安全保证
条款46:最小化互操作
条款47:优先选择安全代码
条款48:掌握相关工具与资源
条款49:为C# 2.0做准备
条款50:了解ECMA标准
#40
使用数据库时,存储过程参数,尽量不要拼接字符串。
数据库要建立索引、使用事务。
ASP.NET合理利用母版页和缓存。
提取字符串注意正则表达式的优化,提高准确性来减少迭代。
算术表达式要多用小括号。
private bool test = false;if(test){;}
结构简单时使用三目运算符。
灵活使用switch。
数据库要建立索引、使用事务。
ASP.NET合理利用母版页和缓存。
提取字符串注意正则表达式的优化,提高准确性来减少迭代。
算术表达式要多用小括号。
private bool test = false;if(test){;}
结构简单时使用三目运算符。
灵活使用switch。
#41
大家都牛啊!
哈哈,顶一下1
哈哈,顶一下1
#42
尽量使用托管代码。
平时写的代码要OOP,然后封装成自己的类库,提高日后开发效率。
多用组合,少用继承。
字符串合理使用Trim()。
实现文件复制时,尽量减少对磁盘读写次数。
平时写的代码要OOP,然后封装成自己的类库,提高日后开发效率。
多用组合,少用继承。
字符串合理使用Trim()。
实现文件复制时,尽量减少对磁盘读写次数。
#43
正是因为DataTable的强大所以才不推荐使用它(不是不能)
考虑下面的代码:
DataTable GetEmployee1() {
return table;
}
Ilist<EmployeeInfo> GetEmployee2() {
return list;
}
void InitInterfaceUsingDataTable() {
DataRow row = GetEmployee1().rows[0];
this.txName = row["EmployeeName"]; // 你确定字段名是EmployeeName吗?
}
void InitInterfaveUsingList() {
EmployeeInfo> employee = GetEmployee2()[0];
this.txName = list.EmployeeName; // 这样写代码很舒服
}
// 再考虑下下下面的情况
// 某天,老板对你说:“嘿,去把EmployeeName改成EmployeeFirstName”
#44
Great!
#45
学习了!
#46
此贴会火... 留名
#47
同意,不过加一点:
使用非托管代码写保密性的算法或很有价值的算法。
#48
楼主可以对那50条分别开贴探讨指导下
#49
如果托管代码用到了非托管资源,最好使用Dispose模式,并且一定要手写代码清理非托管资源
#50
Thread..