string updateSQL = "UPDATE EmpTable SET Name='" +name+ "' WHERE EmpId=" +id;
That code is really messy, and prone to typing errors. What's more, since the string is immutable, it creates three unnecessary garbage string copies in the memory as a result of multiple concatenations.
string updateSQL= string.Format(
"UPDATE EmpTable SET Name='{0}' WHERE EmpId={1}",
name, id);
It also paves the way for clean, easy-to-read code.
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;
}
}
}
So what would happen with the above code if the same exception were handled multiple times and moreover catching many exceptions? Throwing it will definitely add a performance overhead.
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)
}
}
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();
}
And check out the timing data that shows in the following figure:
public bool CheckIfNumeric(string value)
{
bool isNumeric = true;
try {
int i = Convert.ToInt32(value);
}
catch(FormatException exception) {
isNumeric = false;
}
return isNumeric;
}
Since it involves try/catch, it is not the best way. A better approach would be to use int.TryParse as shown below:
int output = 0;
bool isNumeric = int.TryParse(value, out output);
This technique of using int.TryParse, in my opinion is definitely the faster and cleaner way.
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();
}
}
In the above method, the connection dispose is called explicitly in the finally block. In case there is an exception, then the catch block will be executed and after that the finally block will be executed to dispose the connection. So the connection is left in the memory until the finally block is executed. In the .NET Framework, one of the basic guidelines is to release the resource when it is not being used anymore.
public void DALMethod()
{
using (SqlConnection connection = new SqlConnection("XXXXXXXXXX"))
{
connection.Open();
//implement the data access
}
}
When you have a 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.
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";
}
}
In the MyAccount class, a public variable AccountNumber is declared and assigned in the constructor. It is desired that the AccountNumber should be read-only and shouldn't be modified but when declared as shown, the MyAccount class doesn't have any control over it.
public class MyAccount
{
private string _accountNumber;
public string AccountNumber
{
get { return _accountNumber; }
}
public MyAccount()
{
_accountNumber = "XXXXXXXXXXXXX";
}
}
Here the MyAccount class has a good control over the AccountNumber. It is now read-only and cannot be changed by the caller.
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]
}
}
}
In the above scenario... What if the column order in the SQL query fetching data changes? Your application will break for sure! Always access the values through column names; one technique is:
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
}
}
}
The code above won't break, even if the database schema is altered and the column order is changed. Use a constant variable to hold the column names at a single place so that even if the column name changes in the future then you will have to modify the code in only one place.
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (9)
Author
Commented:Commented:
By the way, starlite551, can you verify what PaulHews has pointed out? Is it possible that your timing of for vs. foreach is wrong? If you can verify and report the results as an Author Comment, it would be a good update to this article.
Commented:
Example:
Open in new window
Author
Commented:Commented:
You are right, using numbers to access a data column is not the best option, but using name is not the more eficient option.
the more eficient option is index by DataColumn.
This is importan only on loops.
Note that indexing by string, uses Dictionary to get the datacolumn.
You can code:
public void MyMethod()
{
DataTable dt = DataAccess.GetData();
DataColumn COL_EMP_ID = dt.Columns["EmpId"];
foreach (DataRow row in dt.Rows)
{
int empId = Convert.ToInt32(row[COL_EM
}
View More