Share via


Class inheritance and partial classes in C#

Question

Wednesday, September 20, 2017 4:57 PM

Hello,

Where would I ask questions about Class inheritance and partial classes in C#?

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.

All replies (15)

Wednesday, September 20, 2017 8:12 PM

Right here is the correct place. Those are topics about the C# language, so the C# forum is perfectly appropriate.


Wednesday, September 20, 2017 8:36 PM

Thanks Alberto.

I would like to ask two questions and I hope that is OK.

If I have a partial class defined, do I need to have another partial class with the same class name defined somewhere else?

In other words, can a partial class stand by itself?  Without having the same partial class defined in another part of the same namespace?

If I override a virtual method which is inside a partial class in a different namespace, can I just override a specific statement that is inside the base class method, like a "for each"?

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.


Wednesday, September 20, 2017 9:31 PM

#1:  A partial class may standalone (there doesn't need to be any more parts), but in that case it has to specify all aspects of the class, just like a regular class (e.g. public/internal, base class, abstract, sealed, generics, etc)

#2:  When you override a method in a base class, you override the entire method, you cannot pick and choose the parts that you override, although you can call the base class implementation if you want.  

Note that this applies to all classes.  Details like partial and namespaces don't change that.

If you really need to control small parts of the function like that there are a few possible options.  Such as this:

class Base {
    List<string> stuff;

    public virtual void DoSomething() {
        DoSomethingImpl(item=>Console.WriteLine(item));
    }

    protected void DoSomethingImpl(Action<string> action) {
        foreach (var item in stuff) {
            action(item);
        }
    }
}

class Derived : Base {
    public override void DoSomething() {
        DoSomethingImpl(item=>Debug.Assert(item.Length > 3));
    }
}

Wednesday, September 20, 2017 9:36 PM

Yes, a partial class can stand by itself, in other words, a class can be defined in a single file even if it is decorated with "partial"; you don't need a second file with more content for your partial class.

You can't have portions of a partial class in a different namespaces. They would be different classes even if the class name is the same.

When you override a method, you override the entire method, it can't apply to individual lines. If you need to do this, split the original method into several smaller methods and write an "envelope" method that calls all the parts. If the parts are virtual, you can override only one of them. Also, from an overridden method you can call base.TheMethod. This allows the overridden method to "insert" within itself the content of the base class method that is being overridden.


Thursday, September 21, 2017 5:31 AM

Hello ,
>>do I need to have another partial class with the same class name defined somewhere else?

No, you can't need to create another class file. All the parts will  form the final type at compile time . Of course it suitable for just one part.

>>If I override a virtual method which is inside a partial class in a different namespace,

A class's name includes it's namespace , namespace1.class1 and namespace2.class1 are two completely separate types.So partial class couldn't be in different namespace.

>>can I just override a specific statement that is inside the base class method, like a "for each"?

NO ,Override is usually used to modify  virtual implementation of an inherited method, property,etc,

It is not suitable for overriding a specific statement.

Sincerely,
feih_7

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].


Thursday, September 21, 2017 12:51 PM

Thanks to everybody for their replies.

I created a class that inherits a partial class in another namespace.  I also did an override in my derived class of a virtual method in the base class.

I'm getting one error.  There is no argument given that corresponds to the required formal parameter 'productService'

The base class looks like this:

namespace Nop.Services.ExportImport
{
    /// <summary>
    /// Import manager
    /// </summary>
    public partial class ImportManager : IImportManager
    {
        #region Fields

        private readonly IProductService _productService;

There are about 25 readonly fields.

Thia is my derived class:

namespace Nop.Plugin.Misc.LakesideImport.ExportImport
{
    /// <summary>
    /// Import manager
    /// </summary>
    public class LakesideImportManager : ImportManager
    {
          #region Fields

          private readonly IProductService _productService;

Again, there are the same 25 fields that I copied from the base class.

This is my constructor in the derived class:

          public LakesideImportManager(IProductService productService,
            ICategoryService categoryService){
               this._productService = productService;}

I copied all the constructor parameters from the base class and again there are 25 parameters.  I also copied all 25 assignments in the constructor from the base class.

The error is occurring on the line public LakesideImportManager(IProductService productService,

Any help that anyone can provide to resolve this error would be gratefully appreciated.

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.


Thursday, September 21, 2017 1:03 PM

I think this link is the same issue and provides the appropriate answer: https://stackoverflow.com/questions/30696006/inheritance-with-base-class-constructor-with-parameters

In other words, your derived class must call a base constructor because the base class doesn't provide a parameterless constructor.

public LakesideImportManager(IProductService productService,
            ICategoryService categoryService) : base(productService, categoryService)

I would, however, question exactly what you are trying to achieve. Creating a derived class that duplicates all the properties of base class would seem to counteract the entire point of inheritance!

For example, if you made the properties in the base class protected rather than private then they would be accessible in the derived class (but not to code outside the class). And you then would not even need to create another constructor in the derived class at all.


Thursday, September 21, 2017 1:55 PM

RJP,

Thanks for your help.

I put in the code to call the base class using the ": base" method and the error went away.

>> I would, however, question exactly what you are trying to achieve. Creating a derived class that duplicates all the properties of base class would seem to counteract the entire point of inheritance! <<

I'm not sure of what is required and not required in my derived class.  Do I not need the fields and the assignments inside the constructor of the derived class?

I tried this:

public LakesideImportManager()
{

}

and it still gives the same error.

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.


Thursday, September 21, 2017 2:06 PM

A derived class inherits all the functionality of the base class. It can access all public properties and methods (obviously), but it can also access all protected fields, properties and methods.

Examples here

E.g

public partial class ImportManager : IImportManager
{
   protected readonly IProductService _productService;

   // constructor
   public ImportManager(IProduceService productService)
   {
      _productService = productService;
   }
}

public class LakesideImportManager : ImportManager
{
   // already inherits functionality from base class
   
   public void SomeSpecificMethod()
   {
      // I can access _productService here because it is "protected". No need to re-declare.
       Console.WriteLine(_productService);
   }
}


// sample usage
var importer = new LakesideImportManager(someProductService);
importer.SomeSpecificMethod();

Thursday, September 21, 2017 2:43 PM

I'm sorry.  I'm still not getting this.  It seems like you are showing me in your example that I don't need any fields or a constructor in my derived class.

I removed all that, but now it is giving that same error on this line:

    public class LakesideImportManager : ImportManager

It is also giving errors in the overriden method for all the fields such as _productService.

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.


Thursday, September 21, 2017 3:52 PM

Hi Carneno,

You should never need to duplicate fields and code in a derived class. Any field, property or method in a class can be marked as public, protected or private (these are 'access modifiers')

If you are not sure as to the meanings of this then I suggest you have a read up here.

If you have a look at my previous example you will note that I marked the _productService field as protected (not private as in your original code). This is what allowed me to access it in the derived class.

The result of all this is that the derived class should only contain code that overrides or extends the functionality in the base class.


Thursday, September 21, 2017 4:23 PM

RJP,

I appreciate all of your time and effort to try and help me, but I'm still not getting it.

I set up my derived class just like you showed in your example, but it still gives that error.

I don't know what else to do except to put all the fields, parameters, base parameters and constructor back to way it was when it did not give an error.  According to you that seems to duplicate what the base class does and is not needed in the derived class.

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.


Thursday, September 21, 2017 4:35 PM

If all (protected) fields and the constructor is in the base class then that should be ok and you should not need to declare the fields in the derived class or have a constructor in the derived class at all.

If you do not want the base class to have that constructor (because you don't want it to be initialised that way) then ensure you may need your base class to at least have a parameter-less constructor:

public class ImportManager
{
   protected IProductService _productService;
   ... other fields ...

   public ImportManager()
   {
      empty constructor (or you could set up some default values here)
   }
}

Thursday, September 21, 2017 4:49 PM

RJP,

Thanks for your continued effort to help me to do this inherit project.

Even though I have the source code for the base class, it is part of a package that gets updated ocassionally.

I assumed that inheritance would allow me to use the base class from that source without the need to change that source.

I'm trying to avoid changes to the original source so that I don't need to change it everytime there is an update.

Thanks,
Tony

Stop The World, I want To Get Off! ........... Life Isn't About Waiting For The Storm To Pass ... It's About Learning To Dance In The Rain.


Friday, October 6, 2017 10:17 AM

Hello Carneno,

>>I assumed that inheritance would allow me to use the base class from that source without the need to change that source.

If you want to use base class from source without changing  source code. You should use the " protected virtal " keyword to modify in your base class. protected means that it is visible only inside this class and classes derived from it.virtual means that it can be overriden in derived classes.

The derived class could invoke the base class's members and also you could override the base class method you don't want to call the original code.

Sincerely,

neil hu

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].