当前位置: 移动技术网 > IT编程>开发语言>c# > C#新手常犯的错误汇总

C#新手常犯的错误汇总

2019年07月18日  | 移动技术网IT编程  | 我要评论
本文所述为c#新手常犯的错误,但是实际上很多有经验的程序员也经常犯这些错误,对此特别整理了一下,供大家参考。具体如下: 1、遍历list的错误,比如如下代码:

本文所述为c#新手常犯的错误,但是实际上很多有经验的程序员也经常犯这些错误,对此特别整理了一下,供大家参考。具体如下:

1、遍历list的错误,比如如下代码:

list<string> strlist =newlist<string>
for(int i =0; i<strlist.count; i++)
{
  strlist.removeat(i);
}

这段代码看上去是删除了所有元素,实际上每次调用removeat方法会导致list元素索引重排,最后导致元素没有完全删除。
可以改成:

list<string> strlist =newlist<string>
for(int i =0; i<strlist.count; i++)
{
  strlist.removeat(i);
  i-=1;
}

这样就可以完全删除list中的元素。

2、关于c#常量的错误

比如你写了一个类库,在里面定义了如下常量:

public const string str="first version";

并且在另一个程序里引用了这个类库,如果你修改了这个类库中的常量,发布了一个新的版本,那么再运行之前的程序,你会发现常量还是原来的常量,并没有改变。这是因为c#在编译的时候,常量直接作为元数据嵌入,解决方法是重新编译整个解决方案或者使用属性而不是直接访问常量。

3、当把值类型装箱后,如果拆箱只能拆成原来装箱前的类型,比如:

int32 a=3;
object obj=new object();
//这里装箱成功,不会失败
obj=i;
//拆箱一定会失败
int64 b=(int64)obj;

可以像这样操作:

int64 b =(int64)(int32)obj;

就能完成转型

4、重载==运算符的错误:

using system;
using system.collections.generic;
using system.linq;
using system.text;
namespace useoperator
{
  class program
  {
    static void main(string[] args)
    {
      test t1 = new test();
      t1.myfun();
      console.readline();
    }
  }
  class test
  {
    public void myfun()
    {
      test t = new test();
      if (t == null)
      {
        console.writeline("t为空!");
      }
      else
      {
        console.writeline("t不为空!");
      }
    }
    //存在bug的重载运算法
    public static bool operator ==(test t1, test t2)
    {
      return t2.equals(t1);
    }
    public static bool operator !=(test t1, test t2)
    {
      return !(t1 == t2);
    } 
    //覆盖hashcode
    public override int gethashcode()
    {
      return base.gethashcode();
    }
    public override bool equals(object obj)
    {
      return base.equals(obj);
    }
  }
}

这里的问题在于myfun中会把null传递进==运算符函数,导致运行的时候报错,正确的做法是:

public static bool operator ==(test t1, test t2)
{
  if ((t2 as object) == null)
  {
    return (t1 as object) == null;
  }
  else
  {
    return t2.equals(t1);
  }
}

5、c#中调用结构的属性或者方法必须用new来声明结构变量,否则会出错。

6、如果使用了params使用多个参数,必须判断参数是否为空,否则程序会有隐藏的bug。

7、静态成员在创建第一个实例的时候就会初始化,而且只被初始化一次,不要乱用静态成员。

8、如果使用ref object类型参数接受string类型会出错,这是因为c#要求参数必须使用正确的类型,不加ref是可以的,如果一定要使用ref object接受string类型参数,可以先转型成object,再引用传递。

9、类的构造函数中永远不要调用虚方法,比如:

using system;
using system.collections.generic;
using system.linq;
using system.text;
namespace fransfervirtualfunction
{
  class program
  {
    static void main(string[] args)
    {
      try
      {
        child ch = new child();
      }
      catch (exception ex)
      {
        console.writeline(ex.message);
      }
      console.read();

    }
  }
  public class ref
  {
    public string str = "这是ref类的一个成员";
  }
  public class parent
  {
    protected ref my;
    public parent()
    {
      my = new ref();
      //构造方法中调用了虚方法
      console.writeline(getstring());
    }
    //虚方法
    public virtual string getstring()
    {
      return my.str;    //使用了内部成员
    }
  }
  public class child : parent
  {
    private ref my2;
    public child()
      : base()
    {
      my2 = new ref();
    }
    //重写虚方法
    public override string getstring()
    {
      return my2.str;    //使用了内部成员
    }
  }
}

这里在执行基类的构造函数的时候会执行到派生类的虚方法getstring(),在获取my2.str的时候抛出异常,因为此时派生类对象还没有被构造。

10、在c#和sql server通信时要注意null的含义,在sql server里面这个值代表1900-1-1。sql server的空值可以使用dbnull来表示。

暂时就是这么多了,注意到以上10点可以在编程的时候减少大量bug。

补充:

1、math 三角函数 其中的参数为 弧度值,而非角度值。

2、winform 中的由相对路径引发的bug:具体可以参考winform相对路径的陷阱

3、使用 xml, json 等序列化后的数据格式传递数据时,如果传递的数据为数值型类型,解析时,最好先将其转为string 然后 tryparse 成相应类型。

至于原因:如上的第三点、是装箱和拆箱的问题。

相信本文所述对大家c#程序设计可以带来很大的帮助。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

  • c# 面试必备线程基础知识点

    c# 面试必备线程基础知识点

    线程的知识太多,知识点有深有浅,往深的研究会涉及操作系统、cpu、内存,往浅了说就是一些语法。没有一定的知识积累,很难把线程的知识写得全面,当然我也没有这个能力... [阅读全文]
  • C#使用System.Net邮件发送功能踩过的坑

    C#使用System.Net邮件发送功能踩过的坑

    1.eazyemail邮件发送类库net 类库自带了邮件发送功能。笔者对该类库,从使用的角度进行了二次封装,nuget上可搜索eazyemail,注入容器时通过... [阅读全文]
  • C#基于Modbus三种CRC16校验方法的性能对比

    C#基于Modbus三种CRC16校验方法的性能对比

    1.背景介绍主要应用场景在物联网中,底端设备注册报文的上报,需要对报文的有效载荷(data)进行crc16的复验,验证与设备端的crc校验是否相等,如果相等,报... [阅读全文]
  • 深入谈谈C#9新特性的实际运用

    前言你一定会好奇:“老周,你去哪开飞机了?这么久没写博客了。”老周:“我买不起飞机,开了个铁矿,挖了一年半的石头。谁知铁矿垮了,压死了几条蜈蚣,什么也没挖着。”... [阅读全文]
  • C# 泛型集合的自定义类型排序的实现

    C# 泛型集合的自定义类型排序的实现

    一、泛型集合list<t>排序经sort方法之后,采用了升序的方式进行排列的。二、对自定义类型进行排序定义一个普通类:接下来,将定义的person实... [阅读全文]
  • C#开发中常用的加密解密方法汇总

    相信很多人在开发过程中经常会遇到需要对一些重要的信息进行加密处理,今天给大家分享我个人总结的一些加密算法:常见的加密方式分为可逆和不可逆两种方式可逆:rsa,a... [阅读全文]
  • C# 如何添加错误日志信息

    系统日志系统日志包含了由windows系统组件记录的事件。例如,在启动期间装入驱动程序或其他系统组件失败被记录到系统日志。要查看系统日志: 打开命令提示符。 ... [阅读全文]
  • 关于C#委托三种调用的分享使用

    关于C#委托三种调用的分享使用

    一、同步调用1、同步调用会按照代码顺序来执行2、同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量io操作),可能会让程序停顿很长时间,造成糟糕的用户体验,... [阅读全文]
  • 用c# 自动更新程序

    作者:冰封一夏出处:hzhcontrols官网:首先看获取和更新的接口更新程序program.cs更新程序界面定义服务端接口,你可以用任意接口都行,我这里用we... [阅读全文]
  • c# 生成二维码的示例

    二维码是越来越流行了,很多地方都有可能是使用到。如果是静态的二维码还是比较好处理的,通过在线工具就可以直接生成一张二维码图片,比如:草料二维码。但有的时候是需要... [阅读全文]
验证码:
移动技术网