Home > Net >  How can I use a base type's methods, which return an object of the base type, in my derived typ
How can I use a base type's methods, which return an object of the base type, in my derived typ

Time:05-02

I'm attempting to create a class, ExtendedDataFrame, by inheriting DataFrame from Microsoft.Data.Analysis. The goal is to add a Name property:

using Microsoft.Data.Analysis;

namespace Testing;

public class ExtendedDataFrame : DataFrame
{
    public string Name { get; set; } = String.Empty;

    public ExtendedDataFrame() : base() { }

    public ExtendedDataFrame(string name) : base() => this.Name = name;

    // Implement DataFrame's constructors:
    public ExtendedDataFrame(string name, params DataFrameColumn[] columns) : base(columns)
    {
        this.Name = name;
    }
    
    public ExtendedDataFrame(string name, IEnumerable<DataFrameColumn> columns) : base(columns)
    {
        this.Name = name;
    }
}

I can build an ExtendedDataFrame:

public class Program
{
    public static void Main(string[] args)
    {
        StringDataFrameColumn col = new("foo", 0);
        col.Append("bar");
        col.Append("baz");

        ExtendedDataFrame edf = new("EDF", col);

        ...
     }
}

But I have lost some functionality. DataFrame has a Clone method. I can use DataFrame's Clone method to create a DataFrame:

// Note: Clone() returns a DataFrame object.
DataFrame df = edf.Clone();

However, if I cannot use DataFrame's Clone method to create an ExtendedDataFrame:

ExtendedDataFrame edf2 = (ExtendedDataFrame)df.Clone();

This results in a System.InvalidCastException: Unable to cast object of type 'Microsoft.Data.Analysis.DataFrame' to type 'DataFrameExtension.ExtendedDataFrame'.

This make sense because Clone is returning a DataFrame object and edf2 is an ExtendedDataFrame.

This brings me to my question. Other than Clone, DataFrame has other methdos (like Filter) that return DataFrame objects. Is there some way I can use those methods with ExtendedDataFrame objects? Or, is there another means of adding a Name property to DataFrame?

CodePudding user response:

It sounds like you’re trying to augment the functionality of ‘DataFrame’ by adding additional stuff (like the Name property) and still use the underlying DataFrame logic like Clone() and Filter(), but you wish to also augment those methods to return instances of ‘ExtendedDataFrame’ instead of ‘DataFrame’.

You might consider a composition approach to give you greater control over your augmented class’s public API. The issue with plain inheritance is you can’t change the return type of Clone(), Filter(), etc. without some smelly workarounds.

Using composition, you take in as a parameter (or create internally) a DataFrame object, and wrap all functionality in your own custom functionality.

Like so:

public class ExtendedDataFrame {
    private readonly DataFrame _dataFrame;
    
    public string Name { get; set; }

    public ExtendedDataFrame(string name) {
        this.Name = name;
        this._dataFrame = new DataFrame();
    }

    protected ExtendedDataFrame(string name, DataFrame dataFrame) {
        this.Name = name;
        this._dataFrame = dataFrame;
    }


    public ExtendedDataFrame Clone() {
        return new ExtendedDataFrame(this.Name, this._dataFrame.Clone());
    }

    // Other methods here

}

The caveat is, any DataFrame methods you want to be exposed on your augmented data frame class, you need to manually create methods in your class that call the method on the underlying data frame.

  •  Tags:  
  • c#
  • Related