.NET编程初学者容易犯的错误和容易混淆的概念

原创 2011年01月24日 21:02:00

今天转载了好几篇文章,这篇对偶现在的情况最有用,希望能够对您也有用!?呵!贴在这里!转载自M$中文技术站
一、分不清楚的对象与类

即使是初学者也知道面向对象这个名词。但是很多人搞不清楚“对象”和“类”这两个概念的区别。我不想去解释对象与类的名词概念,这些东西大家翻翻书本就可以找到。

如果你仔细翻阅一下很多IT书籍,会发现,对象(object)与类(class)相互混用。比如,任何一本入门的面向对象书都会告诉你:对象是类的实例。汽车是一个类,而你家的那一辆桑塔纳就是汽车类的一个实例,所以桑塔纳是对象,而汽车就是类。可是,你也会经常发现诸如汽车对象这样的说法,似乎对象又变成了类???

分清楚这个概念,需要知道一点,对象有两个含义:狭义对象和广义对象。看起来有点复杂?但我保证这不是爱因斯坦的相对论。狭义对象是指面向对象编程(OOP)中的对象,狭义对象定义就是:对象是类的实例。广义对象是指面向对象理论和面向对象设计(OOD)中的对象概念,广义对象同时包含类和类的实例两种含义,也就是类也可以称之为广义对象,而类的实例也可以称之为广义对象。

因而,如果一个人或者一本书没有特定针对编程实现,而是泛泛而谈时,对象都是指广义对象,当特指某段程序代码时,对象是指狭义对象。呵呵,没有办法,这就是历史遗留下来所造成的问题。

二、乱用对象继承

我见过一个用ASP.NET的人,他正在编写一个c#代码文件(不是ASP.NET页面),其中写了一个类,他希望在这个类中引用Application中的一个变量,如果是你,你会怎样做?

他是这样做的,比如这个类叫Test,代码如下:

public class Test : System.Web.UI.Page
{
public Test()
{
}

public void MyMethod()
{
object l_value;

l_value = Application["MyVar"];
...
}
}

大家觉得如何?我不知道有多少人会想出这个方法来解决问题。但是他终于跑来找我帮忙,他说这个类一运行就报错了。

说到底,他之所以会将Test类从System.Web.UI.Page继承下来,因为他终于可以在代码中使用Application了。但是这个Application却无法正常工作。Test类并不是一个ASP.NET页面,先不说技术上的问题,仅就面向对象来说就是一个错误的用法,没有承继关系的事物之间是绝对不可以使用继承关系的。如果Human(人类)类从Dog(狗)类继承下来,恐怕没有人赞同吧?因为狗与人之间没有直接的生物关联。

最后提一下上面那个Application不能使用的原因。所有从System.Web.UI.Page继承下来的类都是ASP.NET页面,而每一个ASP.NET页面必须在ASP.NET的进程中进行上下文初始化,也就是该页面必须由ASP.NET的内部进行初始化和创建,直接用new来手动创建,虽然可以在代码使用Application,但是这个Application没有被赋值,所以是null。

三、误解对象方法的作用域

错误的使用对象继承,这样的人确实不少,而不能正确区分对象方法作用域的人多如满天星斗。甚至在一些有多年编程经验的人里
也会犯这种错误。

在一个系统中,看到了别人编写的如下代码:

//产品的数据库操作类
public class ProductionDB
{
public ProductionDB()
{
}

//保存一个产品到数据库中,a_object是一个产品对象实例
public bool SaveProduction(ProductionObject a_object)
{
...
}
//从数据库中删除一个产品,a_object是一个产品对象实例
public bool DeleteProduction(ProductionObject a_object)
{
...
}
//新建一个产品,并返回创建的新产品对象实例
public ProductionObject NewProduction()
{
...
}
//返回指定ID的产品对象
public ProductionObject GetProduction(string a_productionID)
{
...
}
//搜索产品,并返回搜索结果
public ProductionObject[] SearchProduction(object[] a_conditions)
{
...
}
}

我不知道正在看贴的你有没有设计过类似上面这样的代码,也不知道你看到上面代码时是什么心情,反正我看到上面这段代码时差点背过去了,至于是气的背过去还是笑的背过去,我已经分不清楚了。

你会怎样使用这个ProductionDB类来操作产品数据库表?举一个例子:
ProductionObject l_prod;
...
//假设l_prod已经赋值了
ProductionDB l_prodDB = new ProductionDB();
if(l_prodDB.SaveProduction(l_prod)==false) ...
else ...
...

上面是一个典型的使用范例,你看到了,如果要保存一个产品,就必须首先创建一个ProductionDB的实例即new ProductionDB()。问题就在这里了,ProductionDB类中的SaveProduction方法的所有信息全部来自方法参数a_object,也就是方法外部的l_prod变量,而ProductionDB类中除了这5个方法以外,再没有任何其他信息,所以new ProductionDB()有什么意义???为什么要创建一个ProductionDB的实例???

编写者的误解在于,没有区分清楚实例方法与类方法两种方法作用域的区别。凡是像上面这样,方法代码不依赖类的任何信息就应该将方法声明为类方法,而方法依赖和使用类中的成员、信息等,则需要将方法声明为实例方法。

正确的方法编写如下:
public class ProductionDB
{

//保存一个产品到数据库中,a_object是一个产品对象实例
public static bool SaveProduction(ProductionObject a_object)
{
...
}
//从数据库中删除一个产品,a_object是一个产品对象实例
public static bool DeleteProduction(ProductionObject a_object)
{
...
}
//新建一个产品,并返回创建的新产品对象实例
public static ProductionObject NewProduction()
{
...
}
//返回指定ID的产品对象
public static ProductionObject GetProduction(string a_productionID)
{
...
}
//搜索产品,并返回搜索结果
public static ProductionObject[] SearchProduction(object[] a_conditions)
{
...
}
}

将方法声明为static就是类方法,使用方法如下:
ProductionObject l_prod;
...
//假设l_prod已经赋值了
if(ProductionDB.SaveProduction(l_prod)==false) ...
else ...
...

四、滥用数据库连接

滥用数据库连接的人比天上星星还要多的多!!!

我的上面那位程序员也犯下了这个错误,还是那个ProductionDB类,以SaveProduction方法来举例:

public bool SaveProduction(ProductionObject a_object)
{
Connection l_conn;
string l_connString;

l_connString = Application["ConnectionString"];
l_conn = new Connection(l_connString);
...
try
{
try
{
l_conn.Open();
...
}
catch(Exception Eo) {...; return false; }
}
finally
{
l_conn.Close();
}
return true;
}

上面的代码可以正常工作,而且工作的还不错。

但是在某些情况下,机器、软件、数据库、SQL语句等等所有一切都非常的正常,上面代码却会返回false???为什么?因为那个程序员滥用了数据库连接。

每当调用一次SaveProduction方法,系统就会创建一个数据库连接,在方法执行完毕时关闭这个连接,如果是几个人同时测试这段代码,那么几乎不会发生任何问题。

但是如果同时有100个客户调用了SaveProduction方法,会发生什么结果?系统中将在那一霎那间创建100个数据库连接!!!不要说Access这样级别的数据库,就是SQLServer2000也会承受不了。

所以解决方法是不要在一个方法临时创建和关闭数据库连接,不但会造成死机、异常退出等问题,而且也会导致系统性能下降。
正确的方法应该是单独编写一个类或者方法,将所有创建数据库连接的工作放在其中,由这个类来控制数据库连接的数量。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1647150

Java初学者常犯的错误

不含包层次的HelloWorld.javapublic class HelloWorld{ public static void main(String[] args) { System.out.pr...
  • daichanglin
  • daichanglin
  • 2007年03月13日 11:22
  • 551

程序员容易犯的十大错误

1.面向编译器写代码,而不是面向用户 当人们使用编译器创建自己的app时,在把自己的想法诉诸于机器代码的过程中,常常会将那些可以使得编程更为简单却又冗长的语法遗忘于脑后。 无论你使用的是单字母的标识符...
  • u012701023
  • u012701023
  • 2015年07月13日 23:31
  • 810

冯仑《企业领导最容易犯的十大错误》 .

冯仑这样的企业家是从中国经济蛮荒时代过来的人,是先懂江湖,后懂业务的典范。这样的人经历了从混沌到清晰,从传统到现代的历程,对很多问题更能一眼看到本质,而不是那么多空洞的理论和理想主义。这一点,是我们这...
  • yefighter
  • yefighter
  • 2013年01月25日 13:49
  • 1411

.NET编程初学者容易犯的错误和容易混淆的概念

今天转载了好几篇文章,这篇对偶现在的情况最有用,希望能够对您也有用!?呵!贴在这里!转载自M$中文技术站一、分不清楚的对象与类即使是初学者也知道面向对象这个名词。但是很多人搞不清楚“对象”和“类”这两...
  • xiemails
  • xiemails
  • 2004年10月13日 18:03
  • 564

.NET编程初学者容易犯的错误和容易混淆的概念

今天转载了好几篇文章,这篇对偶现在的情况最有用,希望能够对您也有用!?呵!贴在这里!转载自M$中文技术站 一、分不清楚的对象与类即使是初学者也知道面向对象这个名词。但是很多人搞不清楚“对象”和“类”这...
  • qunluo
  • qunluo
  • 2004年07月22日 18:48
  • 1120

前端中容易犯低级错误的地方

由于自己基础比较薄弱,也可以说知识的深度不够,在写前端代码的时候,往往会出现这样那样的低级问题,以及低级错误,在这里我总结出来了,还是那句话,大神可以绕道了     1.关于页面中js文件和css...
  • ZYGG5521
  • ZYGG5521
  • 2015年08月22日 17:01
  • 672

c++新手容易犯的几个错误

1.不清楚unsigned类型的特性 #include #include int  main( ) {  char* str = "Hellow";   for (int i = ...
  • e_wsq
  • e_wsq
  • 2014年05月10日 16:41
  • 548

JAVA开发人员在编写SQL时最容易犯的10个错误

原文网址: 10 More Common Mistakes Java Developers Make when Writing SQL  或 http://blog.jooq.org/2013/08/...
  • qq532814151
  • qq532814151
  • 2013年08月30日 14:04
  • 1340

Java之——程序员容易犯的常见十大错误

1. Array 转 ArrayList 一般开发者喜欢用: List list = Arrays.asList(arr);Arrays.asList() 会返回一个ArrayList,这是Array...
  • l1028386804
  • l1028386804
  • 2016年03月02日 09:59
  • 1315

Python 易犯错误

修改函数默认参数def fun(x=[],y=False): y=True x.append('hello') return x,yif __name__ == '__main...
  • qq_17612199
  • qq_17612199
  • 2016年04月23日 16:21
  • 228
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.NET编程初学者容易犯的错误和容易混淆的概念
举报原因:
原因补充:

(最多只允许输入30个字)