简体   繁体   中英

C# Different class methods called from a generic object/class?

I have a problem that I don't know how to attack. Hopefully someone can kick me in the right direction. =)

I have created a few classes, ie Word, Excel, Microstation. In these classes I have the same functions with the same name that do the same thing (but of course with different code).

The input to the program (Excel add-in) is a file that can be either Word, Excel or Microstation. Depending on the file type I create an instance of the correct class (Word, Excel or Microstation).

When I have created the instance I would like to call a function that will call the instantiated class functions.

I want to do this:

public function RunTheFunctions(??? o)
{
   o.OpenFile();
   o.DoStuff();
   o.SaveFile();
}

instead of:

oWord.OpenFile();
oWord.DoStuff();
oWord.SaveFile();
oExcel.OpenFile();
oExcel.DoStuff();
oExcel.SaveFile();
oMicrostation.OpenFile();
oMicrostation.DoStuff();
oMicrostation.SaveFile();

I have tried:

object o;
Word oWord = new Word();
o = oWord;
o.OpenFile();

But it does not work.

I hope that my question is relatively clear. =)

Regards, S

Create an interface with the required methods and implement it in your concrete classes:

public interface IDocument
{
    void OpenFile();
    void DoStuff();
    void SaveFile();
}

public class Word : IDocument { .... }

public function RunTheFunctions(IDocument o)
{
    o.OpenFile();
    o.DoStuff();
    o.SaveFile();
}

Besides interface solution, which is the correct way to do it, you can also use dynamic as parameter type if .NET Framework >= 4.0. This solution makes sense if Word, Excel and Microstation are third party classes and do not share a common interface or base class. (Actually you can use Adapter Pattern in this case and return to interface solution)

public void RunTheFunctions(dynamic o)
{
    o.OpenFile();
    o.DoStuff();
    o.SaveFile();
}

This will throw an exception at run-time if the provided object does not have a corresponding method.

You can create interface, which would be implemented by your Word, Excel, Microstation classes:

// interface for your document classes
interface IDocument
{
    void OpenFile();
    void DoStuff();
    void SaveFile();
}

// Word implements IDocument
class Word : IDocument
{
    public void OpenFile() { /* ... */ }
    public void DoStuff() { /* ... */ }
    public void SaveFile() { /* ... */ }
}

// later
public function RunTheFunctions(IDocument o)
{
    o.OpenFile();
    o.DoStuff();
    o.SaveFile();
}

// usage
IDocument doc = new Word();
RunTheFunctions(doc);

Make an interface:

public interface ICommonMethods
{
void OpenFile();
void DoStuff();
void SaveFile();
}

make your classes implement it and then do:

ICommonMethods o = new Word();

o.OpenFile();

Assuming OpenFile() and SaveFile() are the same operation for all classes, what you need is the Template Method Pattern

 public abstract class Document
{
    /*Assuming OpenFile and SaveFile are the same for Word, Excel and Microstation */

    public void DoStuff()
    {
        OpenFile();
        DoSpecificStuff();
        SaveFile();
    }

    private void OpenFile()
    {
        //Open the file here.
    }

    protected abstract void DoSpecificStuff()
    {
        //Word, Excel and Microstation override this method.
    }

    private void SaveFile()
    {
        //Save file
    }
}

public class Excel : Document
{

    protected override void DoSpecificStuff()
    {
        //Excel does what it needs to do.
    }
}

public class Word : Document
{

    protected override void DoSpecificStuff()
    {
        //Word does what it needs to do.
    }
}

Then the usage:

    public void SomeFunction()
    {
        Document document = SelectDocument("xlsx");
        document.DoStuff(); //Open file, excel operation then save file.

        document = SelectDocument("docx");
        document.DoStuff(); //Open file, word operation then save file.
    }

    public Document SelectDocument(string fileExtension)
    {
        switch (fileExtension)
        {
            case "docx": return new Word();
            case "xlsx": return new Excel();
            default: return null;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM