When to use classes in C #?

I am relatively new to C #, but with a lot of help from Google search and Stack Overflow. I have already made a number of applications that include working with Office, system services, processes, WMI, SQL, Linq, and Active Directory ...

Although, despite the successes in using these applications, I'm still not sure about many things in C #, such as good code practice and the use of many keywords, etc.

C # classes; I know what I can do with them, I know about constructors and destructors, creation and properties, but I'm not sure when I will use them. So far, I have written all my code in the Form1.cs file inside different methods. These Methods do a number of different things with completely different APIs. This obviously means that trying to save this code can be quite a challenge, and it is becoming increasingly difficult for me to find anything inside my Form1.cs.

My question is for you guys, should I break my code into different classes? I tried to separate the material related to SqlConnection and SqlCommands into a separate class, but without instantiating the same class several times in my Form1.cs. I donโ€™t see it being easier or more useful.

I'm trying to put a new application together, but this time keeping the functionality in my class, I was hoping that someone could tell me that I'm stupid, doing it wrong, or at least giving me some tips.

This application will eventually download my connection string from App.Config, connect to the SQL database, and populate the DataSet with several tables from the database. This is by no means functional, as I cannot solve this problem.

Many thanks:)

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; } } 
+6
source share
3 answers

OOP principles say more or less that you need to break up the material as much as possible so that related things are grouped together in their own class, for example, the SQL material in your example. Another frequently used example is a car example - if you need to deal with car data, you would make a car class containing the appropriate variables, such as maximum speed, name, color, and appropriate methods, for example, drive(double distance) or something like that.

If you do not want to use different objects of this class and need the same behavior at several points, you can prevent several instances in several ways: if all points are in your Form1 , you only need to create an instance of the class as a member of the class, and you can use its in class Form1 . If you need to access it from different classes, you can either have a global variable (which in most cases is considered bad practice) or make the class that you need to access static - so you do not need to create it all.

If your application is really small, you can get away from all this in your Form1 class, but, as you yourself noticed, it can become messy and confusing very quickly. Think of classes as a way to sort code. Think about what is connected with what and what you expect to find together, and put it in classes. If you stick to this, you will get code that is less frustrating to find the code and has a clear and logical structure. You can use things like inheritance when things get more complicated, and you can reuse classes that do things (like database stuff, for example) that may be required in different applications.

This is a very short and very crude description. I myself do not know any good books on this topic (except for those that are intended for beginner novice programmers, which seems out of place here), but I suggest finding it in the OOP or looking for good articles for an introduction to this topic. Personally, I think CodeProject is a good source of articles. Here is one of the OOP .

+6
source

I use the principle of single responsibility as a guide for designing classes. Here is a good discussion of this, with the highlight being:

The fact is that each class must implement a cohesive set of related functions. A simple way to comply with a single responsibility. The principle is to constantly ask yourself, the work of a class is directly related to the name of this class. If you find some methods that do not match the name of the class, you should consider moving these methods to another class.

With that in mind, I think you're right to split the functionality of your sample application into separate classes. Otherwise, you will receive a conglomerate class Form1, which has several responsibilities: reading configuration values, connecting to databases, reading data. As you have noticed, dividing code into separate classes also simplifies understanding and navigation of the program.

+4
source

Think about how your classes encapsulate some kind of functionality. In your case, SQLConn handles database connections, this means that this class owns a database connection, and all traffic should now go through this class. It also means that your myDataSet class must use your SQLConn class for all messages, so you are mistaken when creating an instance of SqlCommand inside it.

I think you can confuse instances with classes in your implementation. You create several instances of the SQLConn class, first in the OnLoad method, where you connect to the database, later in the myDataSet class. This is not the same class value. This way your class myDataSet will use SQLConn, which is not connected to the database.

Instead, you can share the same instance by providing the myDataSet class with the SQLConn instance that you want to work with:

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

This is not a very good design, but it illustrates how to pass an instance directly or directly to a class.

0
source

Source: https://habr.com/ru/post/924611/


All Articles