简体   繁体   中英

Workaround for Multiple Inheritance in C#

I have to implement classes to transfer files to USB ( class USBTransfer ) and over FTP ( class FTPTransfer ). Since both the classes use some common methods (like getting the filename, reading some parameters etc.) so, I have implemented those methods in an another class ( class FileOperations ). I have inherited both the classes (ie class USBTransfer and class FTPTransfer ) from the class FileOperations .

class FileOperations
{
    protected void CommonMethod1();
    protected void CommonMethod2();
}

class USBTransfer : FileOperations
{ 

}

class FTPTransfer : FileOperations
{

}

PROBLEM: During the file transfer operations, I set different states (not using the state machine design pattern though). I want to use a ABSTRACT class for this purpose with the following structure.

abstract class FileTransferStateMachine
{
    //Public
    public enum FileTransferStates { Idle = 0, FileCopyingState = 1, SuccessfullyCopiedState = 2 }
    public static FileTransferStates CurrentState = FileTransferStates.Idle;

    abstract protected void IdleState();
    abstract protected void FileCopyingState();
    abstract protected void SuccessfullyCopiedState();
}

But in C# it is not allowed to have multiple inheritance.

QUESTION: I know that I can use interface. But you cannot have variables and in that case both of my classes (ie class USBTransfer and class FTPTransfer ) will have their own variables for the following

public enum FileTransferStates { Idle = 0, FileCopyingState = 1, SuccessfullyCopiedState = 2 }
public static FileTransferStates CurrentState = FileTransferStates.Idle;

I want to reduce redundancy and want to force to have same variables/methods (hmm...same methods can be achieved by interface) for the state machine.

Question PART-2: I can transfer files to USB or FTP as mentioned above but both the transfer operations have some common states like IdleState , FileCopyingState or SuccessfullyCopiedState which have their corresponding methods (ie IdleState() , FileCopyingState() or SuccessfullyCopiedState() ). I want to FORCE both the classes to implement these methods (ie IdleState() , FileCopyingState() or SuccessfullyCopiedState() ). If any class forgets to implement any method then, I should get a compiler error. Basically, the FileTransferStateMachine should be an interface/abstract class whose methods should be overridden in USBTransfer and FTPTransfer classes (which are already inheriting another class called FileOperations ).

Use composition (and avoid static state members) :

abstract class FileOperations
{
    protected void CommonMethod1();
    protected void CommonMethod2();

    protected FileTransferStateMachine Statemachine { get; set; }
}

Edit, regarding Part 2:

When you want to force the concrete classes to implement each of those methods then an interface IFileTransferStateMachine is exactly right.

You could also derive FileOperations from the StateMachine:
abstract class FileOperations: FileTransferStateMachine { }

but I would use an interface, it can be applied more granular.

Addressing both of the parts you say are a problem:

  • FileTransferStates can be moved out of the class, placed directly in the namespace (probably in its own file). Then it can be used by both implementations without being redefined

  • CurrentState can be made a non-static property (not field). Properties can be put on an interface, so they don't need an abstract class. Properties are highly recommended over fields for public members anyway, and as others have said, static isn't appropriate here.

As others have mentioned, another option is to use one of these two classes as a dependency instead of a base class. Ie using composition instead of inheritance.

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