c# 程序 内存页面错误_C#程序员常犯的7个错误

c# 程序 内存页面错误

介绍
(Introduction
)

在编程中犯错误是不可避免的。 即使是很小的错误也可能会造成巨大的损失。 明智的做法是从错误中吸取教训,并尽量避免重蹈覆辙。 在本文中,我将重点介绍我认为是C#开发人员最常犯的错误。


Note:  These mistakes are not the 注意:这些错误不是 worst, or most fatal mistakes, but they show up in a lot of C# code and

they should be avoided.

应该避免它们。



1.使用Format()进行有效的字符串操作 (1. Use Format() for efficient string operations)

在.NET Framework中,String数据类型始终是不可变的类型。 修改字符串后,它始终会创建一个新副本,而不会更改原始副本。 许多开发人员使用VB或Javascript风格的技术来构建字符串:
string updateSQL = "UPDATE EmpTable SET Name='" +name+ "' WHERE EmpId=" +id;

The better approach is to use string.Format() since it internally uses StringBuilder which is mutable:

更好的方法是使用string.Format(),因为它在内部使用可变的StringBuilder:

string updateSQL= string.Format(
    "UPDATE EmpTable SET Name='{0}' WHERE EmpId={1}",
    name, id);

2.避免深入嵌套异常处理 (2. Avoid deeply-nesting exception handling)

打算编写嵌套方法的开发人员最终会对每个方法进行异常处理,如以下代码所示:
public class NestedExceptionHandling
{
      public void MainMethod()
      {
          try  {
              ChildMethod1();
          }
          catch (Exception exception)  {
              //Handle exception
          }
      }
      private void ChildMethod1()
      {
          try  {
              ChildMethod2();
          }
          catch (Exception exception)   {
              //Handle exception
              throw;
          }
      }
     private void ChildMethod2()
      {
          try  {
              //some implementation
          }
          catch (Exception exception) {
              //Handle exception
              throw;
          }
      }
}

I try to avoid this by putting the exception handling in a single place; that is in the MainMethod as shown below:

我试图通过将异常处理放在一个地方来避免这种情况。 在MainMethod中,如下所示:

public class NestedExceptionHandling
  {
      public void MainMethod()
      {
          try  {
              //some implementation
              ChildMethod1();
          }
          catch(Exception exception)  {
              //Handle exception
          }
      }
  
      private void ChildMethod1()
      {
          ChildMethod2();      // note: No per-method try/catch
      }
        private void ChildMethod2()
      {
          //some implementation (no per-method try/catch)
      }
  }

3.避免在大量馆藏中使用[i] foreach [/ i] (3. Avoid using [i]foreach[/i] on huge collections)

Most developers prefer to use a foreach loop than a for loop because foreach is easier to use. This will however prove to be costly when working with collections with a large amount of data. Consider the below sample in which I am looping through the same DataTable using for and foreach.

for循环相比,大多数开发人员更喜欢使用foreach循环因为foreach更易于使用。 但是,在处理具有大量数据的集合时,这将被证明是昂贵的。 考虑下面的示例,其中我使用for和foreach遍历同一DataTable。

static void Main(string[] args)
  {
      DataTable dt = PopulateData();
      Stopwatch watch = new Stopwatch();
  
      // ------------------------------------------- for loop
      watch.Start();
      for (int count = 0; count < dt.Rows.Count; count++)
      {
          dt.Rows[count]["Name"] = "Modified in For";
      }
      watch.Stop();
      Console.WriteLine("Time taken in For loop: {0}", watch.Elapsed.TotalSeconds);
  
      // ------------------------------------------- foreach loop
      watch.Start();
      foreach (DataRow row in dt.Rows)
      {
          row["Name"] = "Modified in ForEach";
      }
      watch.Stop();
      Console.WriteLine("Time taken in For Each loop: {0}", watch.Elapsed.TotalSeconds);
  
      Console.ReadKey();
  }
Loops : Which is more efficient?

For bigger collections, always use a for loop in cases where looping is required.

对于较大的集合,在需要循环的情况下始终使用for循环。

4.使用TryParse()验证原始数据类型 (4. Use TryParse() to validate primitive data types)

许多开发人员并不了解可用于验证诸如System.Int32之类的原始数据类型并最终执行自定义实现的内置方法。 下面的函数是一种典型的自定义实现,用于验证给定的字符串是否为数字。
public bool CheckIfNumeric(string value)
{
      bool isNumeric = true;
      try  {
          int i = Convert.ToInt32(value);
      }
      catch(FormatException exception)  {
          isNumeric = false;
      }
      return isNumeric;
}
int output = 0;
bool isNumeric = int.TryParse(value, out output);

int.TryParse, in my opinion is definitely the faster and cleaner way.

我认为int.TryParse绝对是更快更清洁的方式。

5.对实现IDisposable的对象的低效率处理 (5. Inefficient handling of objects implementing IDisposable)

在.NET Framework中,处理对象与使用对象一样重要。 理想的方法是在类中实现IDisposable接口的dispose方法,因此在使用该类的对象之后,可以通过调用dispose方法来对其进行处理。

Below is a sample where an SqlConnection object is created, used and disposed:

下面是创建,使用和处置SqlConnection对象的示例:

public void DALMethod()
  {
      SqlConnection connection = null;
      try  {
          connection = new SqlConnection("XXXXXXXXXX");
          connection.Open();
          //implement the data access
      }
      catch (Exception exception)  {
          //handle exception
      }
      finally  {
          connection.Close();
          connection.Dispose();
      }
}

Here is a better way of calling dispose:

这是调用dispose的更好方法:

public void DALMethod()
{
      using (SqlConnection connection = new SqlConnection("XXXXXXXXXX"))
      {
          connection.Open();
          //implement the data access
      }
}

using block as shown above, the dispose method on the object will be called as soon as the execution exits the block.  That ensures that the SqlConnection resource is disposed and released at the earliest possilbe moment. You should also note that this will work on classes which implement the IDisposable interface.

使用如上所述的块,一旦执行退出该块,将立即调用对象上的dispose方法。 这确保了SqlConnection资源在最早的可能时刻被释放和释放。 您还应该注意,这将对实现IDisposable接口的类起作用。

6.滥用公共成员变量 (6. Misuse of public member variables)

这听起来很简单,但实际上可能导致滥用已声明的公共变量,并可能获取类的意外用法。 考虑以下示例:
static void Main(string[] args)
{
      MyAccount account = new MyAccount();
      // The caller is able to set the value which is unexpected
      account.AccountNumber = "YYYYYYYYYYYYYY";
      Console.ReadKey();    
}
 
public class MyAccount
{
      public string AccountNumber;

      public MyAccount()
      {
          AccountNumber = "XXXXXXXXXXXXX";
      }
}

A better way to declare a public variable like AccountNumber is to use a property:

声明诸如AccountNumber之类的公共变量的更好方法是使用属性:

public class MyAccount
{
      private string _accountNumber;
      public string AccountNumber
      {
          get { return _accountNumber; }
      }
      public MyAccount()
      {
          _accountNumber = "XXXXXXXXXXXXX";
      }
}

7.使用硬编码索引访问DataTable值 (7. Accessing a DataTable values using a hard-coded index)

我经常注意到,大多数程序员使用列索引从DataTable访问数据,如下所示:
public class MyClass
{
      public void MyMethod()
      {
          DataTable dt = DataAccess.GetData();  // fetch data from the database
          foreach (DataRow row in dt.Rows)
          {
              // BAD: Accessing data through column index
              int empId = Convert.ToInt32( row[0] );   // BAD: hardcoded row[0]
          }
      }
}
public class MyClass
{
      private const string COL_EMP_ID = "EmpId";   
      public void MyMethod()
      {
          DataTable dt = DataAccess.GetData();
          foreach (DataRow row in dt.Rows)
          {
              //  GOOD: Accessing data through column name
              int empId = Convert.ToInt32(row[COL_EMP_ID]);  // use defined constant
          }
      }
}

结论
(Conclusion
)

我希望您可以从我自己和其他程序员过去犯的错误中学习。 这是我见过的七个最常见的错误-我相信 you have seen others ones, too!   Please feel free to utilize the comments section to showcase the conflicts and let me know what you think are other common issues as well.

翻译自: https://www.experts-exchange.com/articles/3712/7-Common-Mistakes-Made-By-Programmers-in-C.html

c# 程序 内存页面错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值