skip to Main Content

Understand that Override and New Keywords can help to either implement the base methods or the child methods. But when using the real time examples, I don’t see any virtual methods in the following project. Can someone help me to understand why

  1. virtaul was not used for the BeginTran method in the ServiceBase Class.
  2. And if making virtual base method and using new in derived class implements the base method why there is a call for the base.BeginTran() explicitly.

Please help to clarify the doubts.

public sealed class SearchService : ServiceLogic 
    {
        public new SearchService BeginTran()
        {
            base.BeginTran();
            return this;
        }
public abstract class ServiceLogic : ServiceBase
{
}

public abstract class ServiceBase : IDisposable
{
    public void BeginTran()
        {
            this.proxy.GetContext().BeginTran();
        }
}

Also, the following is my Controller code

 using (var svc = new SearchService())
       {
            return svc.getAll();
     }

Calling the Web Service

public sealed class SearchService: ServiceLogic
    {
        public new SearchService BeginTran()
        {
            base.BeginTran();
            return this;
        }
        public SearchService Delete(Guid id)
        {
            Let<User>().Delete(id);
            return this;
        }
        public User GetAll(Guid id)
        {
        }

So I would like to know why there was a need to call the BeginTran and return another object of a sealed SearchService class as earlier we did create an instance using var svc = new SearchService().

2

Answers


  1. Override/Virtual and New actually solve two different problems and have two different uses.

    Here is an example of virtual/override. Where the base class and the child class both return the exact same type (void).

    public abstract class ServiceBase 
    {
        public virtual void BeginTran()
        {
            base.BeginTran();
        }
    }
    
    public sealed class SearchService : ServiceBase 
    { 
        public override void BeginTran()
        {
            base.BeginTran();
        }
    }
    

    However, notice in your example using new you have this :

    public sealed class SearchService : ServiceBase 
    { 
        public new SearchService BeginTran()
        {
            base.BeginTran();
            return this;
        }
    }
    

    Your return type is now SearchService, not void. Because you have changed the return type, you can’t "Override" the method, you need to use the new keyword to return a different type. This is called method "hiding".

    There is also other side effects to this. Essentially the two methods are not connected, so polymorphism can often completely break and do unexpected things.

    I would personally say that method hiding, or using the new keyword is a direct contradiction of the Liskov Principle which says that types can be replaced by subtypes without altering the program. In your case, that would not be true if you change the return type. Bit more info on that here : https://dotnetcoretutorials.com/2019/10/20/solid-in-c-liskov-principle/

    In 15+ years of C# experience, I have used the new keyword maybe a handful of times, and almost always when trying to override a library method and bastardize the code.

    Login or Signup to reply.
  2. When you do public new SearchService BeginTran() you are not creating anything. That isn’t creating an instance of the class. That new is the same word that you use to create instances but here has another meaning: change the signature of a method or override a non virtual method in base class.

    The unique instance that you create is this one:

    using (var svc = new SearchService())
    

    Sometimes, when you control the method to call, you can create another method and use it instead of override with new keyword. For example:

    public sealed class SearchService : ServiceLogic 
    {
        public SearchService StartTran()
        {
            base.BeginTran();
            return this;
        }
    

    You can’t do this when the invocation it’s done in some method of the base class, called indirectly. In that case, you must override that method. But in this case, you can simply create another method.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search