什么时候在C#中使用类?

问题描述:

我对C#语言比较陌生,但有很多来自谷歌搜索和堆栈溢出的帮助我已经完成了许多应用程序,包括与Office,系统服务,进程,WMI,SQL,Linq和Active目录...什么时候在C#中使用类?

虽然尽管有与得到这些应用程序功能的成功我仍然不确定在C#语言的许多东西,如良好的代码实践和使用许多关键字等..

C#类;我知道我可以用它们做什么,我知道构造函数和析构函数,实例化和属性,但我不确定,当我应该使用它们时。到目前为止,我已经在我的Form1.cs文件中写入了所有不同的方法。这些方法使用完全不同的API来做一系列不同的事情。这显然意味着试图维护该代码可能会变得非常困难,并且我发现它越来越令人沮丧,因为我的Form1.cs中找不到任何内容。

我对你们的问题是我应该把我的代码分成不同的类吗?我试图将与SqlConnection和SqlCommands相关的东西分离成一个单独的类,但是没有在Form1.cs中多次实例化同一个类,我看不出这样做更容易或者没有任何好处。

我一直在拼凑一个新的应用程序,但这次保留了它自己的类的功能,我希望有人能告诉我我很愚蠢,做错了或至少给我一些指导。

此应用程序最终会从App.Config加载我的连接字符串,连接到SQL数据库并使用数据库中的多个表填充DataSet。由于我无法解决整个课程问题,所以这绝不是功能性问题。

非常感谢:)

partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    string myConnectionString; 

    private void Form1_Load(object sender, System.EventArgs e) 
    { 
     AppConfig cfg = new AppConfig(); 
     if (cfg.loadConfig()) 
     { 
      myConnectionString = cfg.myConnectionString(); 
     } 

     if (!String.IsNullOrEmpty(myConnectionString)) 
     { 
      SQLConn SQL = new SQLConn(); 
      if (SQL.createConnection(myConnectionString)) 
      { 
       MessageBox.Show("Connected!"); 
      } 
     } 
    } 
} 

class myDataSet 
{ 
    DataSet DataSet() 
    { 
     DataSet ds = new DataSet(); 

     SQLConn sql = new SQLConn(); 

     return ds; 
    } 

    public void fillData() 
    { 
     try 
     { 
      SqlCommand sqlCmd = new SqlCommand("SELECT * FROM hardware");     
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 
} 

class SQLConn : IDisposable 
{ 
    SqlConnection sqlConn; 
    public bool createConnection(string myConnectionString) 
    { 
     sqlConn = new SqlConnection(); 
     sqlConn.ConnectionString = myConnectionString; 
     try 
     { 
      sqlConn.Open(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     return false; 
    } 

    public void Dispose() 
    { 
     if (sqlConn.State == ConnectionState.Open) 
     { 
      sqlConn.Close(); 
      sqlConn.Dispose(); 
     } 
    } 
} 

class AppConfig 
{ 
    Configuration cfg; 

    public bool loadConfig() 
    { 
     try 
     { 
      cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
      if (!File.Exists(cfg.FilePath)) 
      { 
       MessageBox.Show("No configuration file"); 
      } 
      return true; 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     return false; 
    } 

    public string myConnectionString() 
    { 
     string connectionString = ConfigurationManager.ConnectionStrings["IT_ProjectConnectionString"].ConnectionString; 
     return connectionString; 
    } 
} 
+8

您需要详细了解面向对象编程和更高版本的设计模式 – Habib

+0

当*您*希望创建一个新的*类型*。 – adatapost

+1

你的代码充斥着类。你在问什么时候把它们放在自己的文件中?必须同意@Habib你有两件事要在这里忘记。 –

OOP背后的原理或多或少地说你应该尽可能地分割东西,以便相关的东西在他们自己的类中被组合在一起,就像你的例子中的SQL东西。另一个经常使用的例子是汽车 - 如果你需要处理汽车的数据,你会制作一个汽车类,其中包含相关变量,如最高速度,名称,颜色和适当的方法,例如drive(double distance)或类似的东西。

如果您不想要该类的不同对象,并且在多个点上需要相同的行为,则可以通过多种方式防止多个实例:如果所有点都在Form1中,则只需将该类实例化为一个班级成员,你可以在整个Form1课程中使用它。如果你需要从不同的类访问它,你可以有一个全局变量(这被认为是大多数不好的做法),或者让你需要访问的类访问static - 这样,你根本不需要实例化它。

如果您的应用程序非常小,您可能会忘记将它全部放在Form1课程中,但正如您自己发现的那样,它可能会很快变得混乱和混乱。将类视为排序代码的机会。想想什么与什么有关,以及你期望找到什么,并将这些东西放在课堂上。如果你坚持这样做,你最终得到的代码不会令人沮丧地找到代码并且具有清晰和合乎逻辑的结构。一旦事情变得更加复杂,您可以利用继承之类的东西,并且可以重用您在不同应用程序中可能需要的东西(例如,数据库内容)的类。

这是一个非常短暂和非常粗略的描述。我自己并不知道有关这个主题的任何好书(除了那些用于全部编程初学者的书,这在这里看起来不合适),但是我建议找到一本关于面向对象编程或寻找关于该主题的优秀介绍文章。我个人认为CodeProject是一个很好的文章来源。 Here is one on OOP

+0

谢谢,我认为你几乎击中了头部,这是我正在寻找的那种指导。您还向我展示了如何实际使用关键字'static',因为我不知道“静态”类不需要实例化,太棒了! 我想我已经有了正确的想法,并且我想使用类来从我的Form1类中划分功能,但是我不确定是否以正确的方式进行。 再次感谢:) – Robula

+0

伟大的我可以帮助你。我担心我的回答过于复杂 - 我有一种习惯用一种非常奇怪的方式来解释事物,但对我来说似乎没有任何意义:) – Christian

我用的是单一职责原则为指导,以设计类。这里是一个很好的discussion,与最关键的一点福利:

的一点是,每类应该实现一个有凝聚力的一套 相关的功能。遵循单一责任的简单方法原理是不断地问自己,每个方法的操作和该类的名称是直接相关的。如果 你发现一些方法不符合班级名称,你应该考虑将这些方法移到另一个班级。

考虑到这一点,我认为你是正确的将示例应用程序的功能拆分为不同的类。否则,您最终将拥有一个集团Form1类,它具有多个职责:读取配置值,连接到数据库,读取数据。正如您所看到的那样,将代码拆分为不同的类也使得程序更易于理解和导航。

+0

谢谢菲利普,我认为这是我需要的那种信息。现在阅读。 :) – Robula

想想你的类封装了某种功能。在你的情况下,SQLConn正在处理到数据库的连接,这意味着这个类拥有数据库连接,并且所有流量现在都应该通过这个类。这也意味着你的myDataSet类应该利用你的SQLConn类来进行所有的通信,因此它是一个错误,你实例化了一个SqlCommand。

我想你可能会在实现中混淆实例和类。您正在创建类SQLConn的多个实例,首先在您的OnLoad方法中连接到数据库,稍后在myDataSet类中。这是不是相同类的例子。因此,您的myDataSet类将使用未连接到数据库的SQLConn。

您可以改为通过提供myDataSet类与SQLConn 实例共享相同的情况下,你希望它去努力:

public myDataSet(SQLConn conn) 
{ 
    SQLConn sql = conn; 
} 

{ 
    SQLConn conn = new SQLConn(); 
    conn.createConnection(...); 
    myDataSet ds = new myDataSet(conn); 
} 

这还不是很好的设计,但它说明了如何传递实例与直接引用类。

+0

谢谢西蒙,尽我所能避免不好的设计和实践。之前,我曾经将Form1 Class传递给其他类,以便直接从另一个类中访问我的Form1数据,而我最近学到的是* bad *。感谢您清理我对实例的理解。 – Robula