Tuesday 23 July 2019

When to use an abstract class vs. interface in C#

When to use an abstract class vs. interface in C#

Understanding the differences between an abstract class and interface is key to designing loosely coupled and extensible applications



When designing applications, it is important to know when to use an abstract class and when to use an interface. Although abstract classes and interfaces seem similar in some ways, there are key differences that will determine which is the best choice for what you’re trying to accomplish. In this blog post I’ll discuss those differences and how to decide when to use which.

The short answer: An abstract class allows you to create functionality that sub classes can implement or override. An interface only allows you to define functionality, not implement it. And whereas a class can extend only one abstract class, it can take advantage of multiple interfaces. 

C# abstract class explained

An abstract class is a special type of class that cannot be instantiated. An abstract class is designed to be inherited by sub classes that either implement or override its methods. In other words, abstract classes are either partially implemented or not implemented at all. You can have functionality in your abstract class—the methods in an abstract class can be both abstract and concrete. An abstract class can have constructors—this is one major difference between an abstract class and an interface. You can take advantage of abstract classes to design components and specify some level of common functionality that must be implemented by derived classes.

C# interface explained

An interface is basically a contract—it doesn’t have any implementation. An interface can contain only method declarations; it cannot contain method definitions. Nor can you have any member data in an interface. Whereas an abstract class may contain method definitions, fields, and constructors, an interface may only have declarations of events, methods, and properties. Methods declared in an interface must be implemented by the classes that implement the interface. Note that a class can implement more than one interface but extend only one class. The class that implements the interface should implement all its members. Like an abstract class, an interface cannot be instantiated.


Should I use an abstract class or an interface?

Abstract classes provide you the flexibility to have certain concrete methods and some other methods that the derived classes should implement. By contrast, if you use interfaces, you would need to implement all the methods in the class that extends the interface. An abstract class is a good choice if you have plans for future expansion – i.e. if a future expansion is likely in the class hierarchy. If you would like to provide support for future expansion when using interfaces, you’ll need to extend the interface and create a new one.

On a different note, it is easy to add a new interface to the hierarchy if need be. However, if you already have an abstract class in your hierarchy, you can’t add another—i.e., you can add an abstract class only if none are available. You should use an interface if you want a contract on some behavior or functionality. You should not use an interface if you need to write the same code for the interface methods. In this case, you should use an abstract class, define the method once, and reuse it as needed. Do use interfaces to decouple your application’s code from specific implementations of it, or to restrict access to members of a certain type.

By using interfaces, you can, for example, include behavior from multiple sources in a class. That capability is important in C# because the language doesn’t support multiple inheritance of classes. In addition, you must use an interface if you want to simulate inheritance for structs, because they can’t inherit from another struct or class.

Implicit and explicit interface implementations

Interfaces can be implemented implicitly or explicitly. Let me explain how these two implementations differ. Consider an interface called IBusinessLogic.


public interface IBusinessLogic
{
void Initialize();
}

The following class named BusinessLogic implements the IBusinessLogic interface.

public class BusinessLogic : IBusinessLogic
{
public void Initialize()
{
//Some code
}
}

You can create an instance of the BusinessLogic class explicitly and then call the Initialize() method as shown below.

IBusinessLogic businessLogic = new BusinessLogic();
businessLogic.Initialize();

The following code snippet illustrates how you can implement the IBusinessLogic interface implicitly.

public class BusinessLogic : IBusinessLogic
{
void IBusinessLogic.Initialize()
{
}
}

You can now invoke the Initialize() method the same way using a reference to the IBusinessLogic interface. The difference in the two approaches is that when you implement the interface explicitly in your class, you are constrained to invoking a method of your interface using a reference to the interface only. Therefore, the following code snippet would not work, i.e. would not compile.



Friday 25 January 2019

pass parameters in RedirectToAction from one controller to another

in First controller action method

               var res = new ResponseModel();   // with many properties

                        //var routeValues = new RouteValueDictionary {
                        //  { "res", JsonConvert.SerializeObject(res) }
                        //};

                        //return RedirectToAction("Index", "Customer", routeValues);

In Customer controller index method

        public ActionResult Index(string res)
        {
            if (!string.IsNullOrEmpty(res))
            {
                var paymentRes = JsonConvert.DeserializeObject<ResponseModel>(res);
                if (paymentRes.IsSuccessful)
                {
                    ViewBag.paymentMessage = paymentRes.Message;
                }
                else
                {
                    ViewBag.paymentMessage = paymentRes.ErrorMessage;
                }
            }
            return View();
        }