Please explain the usefulness of abstract methods in C #

Just a 5-minute review will be enjoyable ....

+7
c #
source share
11 answers
public abstract class MyBaseController { public void Authenticate() { var r = GetRepository(); } public abstract void GetRepository(); } public class ApplicationSpecificController { public override void GetRepository() { /*get the specific repo here*/ } } 

This is just some dummy code that represents some real-world code that I have (for brevity, this is just a sample code)

I have 2 ASP MVC applications that do pretty similar things. The security / session logic (along with other things) is the same in both cases. I abstracted the basic functionality as in the new library, which they both inherit from. When the base class needs things that can only be obtained from a real implementation, I implement them as abstract methods. Therefore, in the above example, I need to output user information from the database to perform authentication in the base library. To get the correct database for the application, I have an abstract GetRepository method that returns the repository for the application. From here, the base can call some repo method in order to get information about the user and continue checking or something else.

When you need to make changes to authentication, I now only need to upgrade one lib instead of duplicating the efforts in both. In short, if you want to implement some functionality, but not all, then the abstract class works fine. If you do not want to use the functionality, use the interface.

+10
source share

Just look at the Template method template .

+9
source share
 public abstract class Request { // each request has its own approval algorithm. Each has to implement this method public abstract void Approve(); // refuse algorithm is common for all requests public void Refuse() { } // static helper public static void CheckDelete(string status) { } // common property. Used as a comment for any operation against a request public string Description { get; set; } // hard-coded dictionary of css classes for server-side markup decoration public static IDictionary<string, string> CssStatusDictionary } public class RequestIn : Request { public override void Approve() { } } public class RequestOut : Request { public override void Approve() { } } 
+7
source share

Using an abstract method is very common when using the Template method template . You can use it to determine the skeleton of the algorithm and subclasses to modify or refine certain stages of the algorithm without changing its structure.

Take a look at the “real world” example on the doFactory Template Method Pattern page.

+1
source share

A good example is the .NET Stream class. The Stream class includes basic functions that are implemented by all threads, and then specific threads provide specific implementations for real interaction with I / O.

+1
source share

The basic idea is for the abstract class to provide the skeleton and basic functionality and allow the concrete implementation to provide exact details.

Suppose you have an interface with ... +20 methods, for example, with the List interface.

 List {interface } + add( object: Object ) + add( index:Int, object: Object ) + contains( object: Object ): Bool + get( index : Int ): Object + size() : Int .... 

If someone needs to provide an implementation for this list, he must implement +20 methods each time.

An alternative could be the presence of an abstract class that already implements most of the methods and allows the developer to implement several of them.

for example

To implement a non-modifiable list, the programmer only needs to extend this class and provide implementations of the get (int index) and size () methods

 AbstractList: List + get( index: Int ) : Object { abstract } + size() : Int { abstract } ... rest of the methods already implemented by abstract list 

In this situation: get and size are abstract methods that the developer must implement. The rest of the functionality may already be implemented.

 EmptyList: AbstractList { public overrride Object Get( int index ) { return this; } public override int Size() { return 0; } } 

Although this implementation may seem absurd, it would be useful to initialize the variable:

  List list = new EmptyList(); foreach( Object o: in list ) { } 

to avoid null pointers.

+1
source share

Used it for the home version of Tetris, where each type of Tetraminos was a child of the tetramino class.

0
source share

You can use an abstract method (instead of an interface) at any time when you have a base class that actually contains some implementation code, but there is no reasonable default implementation for one or more of its methods:

 public class ConnectionFactoryBase { // This is an actual implementation that shared by subclasses, // which is why we don't want an interface public string ConnectionString { get; set; } // Subclasses will provide database-specific implementations, // but there nothing the base class can provide public abstract IDbConnection GetConnection() {} } public class SqlConnectionFactory { public override IDbConnection GetConnection() { return new SqlConnection(this.ConnectionString); } } 
0
source share

For example, suppose you have classes that match rows in your database. You might want these classes to be considered equal when their identifier is equal, because this is how the database works. This way you can do abstract identification because it will allow you to write code that uses the identifier but does not implement it before you learn about the identifier in specific classes. This way you avoid implementing the same equals method in all entity classes.

 public abstract class AbstractEntity<TId> { public abstract TId Id { get; } public override void Equals(object other) { if (ReferenceEquals(other,null)) return false; if (other.GetType() != GetType() ) return false; var otherEntity = (AbstractEntity<TId>)other; return Id.Equals(otherEntity.Id); } } 
0
source share

I am not a guy from C #. Remember if I use Java? The principle is the same. I used this concept in the game. I calculate the armor value of different monsters in very different ways. I suppose I could track various constants, but this is much simpler conceptually.

 abstract class Monster { int armorValue(); } public class Goblin extends Monster { int armorValue() { return this.level*10; } } public class Golem extends Monster { int armorValue() { return this.level*this.level*20 + enraged ? 100 : 50; } } 
0
source share

Example

 namespace My.Web.UI { public abstract class CustomControl : CompositeControl { // ... public abstract void Initialize(); protected override void CreateChildControls() { base.CreateChildControls(); // Anything custom this.Initialize(); } } } 
0
source share

All Articles