Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
We are about to start a project right from scratch. As per the design discussions i am thinking to bring this topic.
Most of the times,I have seen that Abstract classes were being used just to provide some default/common behavior with some concrete methods.
So, i thought of defining those concrete methods as Extension methods for the Interface i am going to develop in place of Abstract classes.
Can someone guide me regarding my design decision. If you are not going to agree with my point please justify your argument with possible scenario/issues which we can face in case of doing so. So, that it will improve my knowledge.
Both approaches are very very different.
Using an abstract class and though abstract/virtual methods, you allow the derived classes to override a behavior which is not the case for extension method. Extension methods are extensions at the end of the day, they are not part of the type and are hard to spot when someone is examining the API and the features the type provides.
Second point, creating an extension method for a type that you create yourself is not that logical IMHO. Using a base Abstract class keeps your hierarchy clear and keeps your model open for modifications of overridden behaviors.
Extension methods were introduced in C# because a very particular requirement.
When they were designing LINQ they realized that they wouldn't want to create a new interface which would contain all known LINQ methods like Where or Select, because it would mean that any enumerable or collection implementation would need to implement it.
Above mentioned fact has an important drawback: it would need to extensively change the source code of a lot of classes from the Base Class Library and any third-party library or project implementing custom collections couldn't take advantage of LINQ at all.
Then they thought about an approach that could directly work with iterators (i.e. IEnumerator<T>) and that could be compatible with any IEnumerable<T> without having to modify any existing code but just adding new code to new assembly members.
And they invented extension methods, which would be implemented like static methods and they would act as instance members of a given type.
Since the inception of extension methods, they've been implemented in many other scenarios, but they always cover these two use cases:
I've a large code base and I want to offer a functionality to all types deriving (classes) or implementing (interfaces) some other type without having to modify them implementing a new interface across a lot of code (increasing the chance of introducing new bugs).
I don't own the source code of some project and I want to extend some types to support some new methods.
Anything outside these use cases is an abuse of extension methods.
Extension methods aren't a replacement to regular class-based object-oriented programming.
Basically you could extend every class or interface - nothing else is done with the Linq-extension methods.
However you can not define those methods directly in the interface, you allways need a static public class that contains those extensions.
To answer your questions I doubt that defining a default-behaviour within extension-methods is a good thing as it completely compromizes the actual intention of that interface. When creating an extension-method all instances of that (extented) class/interface share those methods, thus what you´re doing is to say every instance of my interface is able to be treated as my abstract class.
Having said this you should differ between the behaviour (the interface) and the actual processing (the class). Mixing both will eventually make your design quite complicated.
Next is by defining extension-mtehods you completely bypass inheritance. So what if you want to override the default-behaviour? You would be lost defining them as new or any different wewird workaround because your design was not open for inheritance at all.
Last point from my view is that you should use extension-methods for classes you don´t have control about. However when you can modify the code you´ll probably won´t use them.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
In Entity Framework 6 AddRange method has been introduced. It's great for big inserts because DbSet.Add method always trigger DetectChanges which extremely slows down the process. I've just wanted to use some existing code based on IDbSet interface when realized that it doesn't have AddRange method. It exists only in DbSet class.
I googled a little bit and found this discussion - http://forums.asp.net/t/1978828.aspx?Why+is+there+no+AddRange+method+for+System+Data+Entity+IDbSet+T+ - but there's no clear conclusion about the reason why actually AddRange method does not exist in IDbSet interface.
Is it a bug or is there some good reason for it not to be there? Any ideas?
UPDATE
Here https://entityframework.codeplex.com/workitem/2781 Microsoft gave me an answer:
This is by design. The interface approach wasn't a good one for DbSet because adding members breaks any existing applications that implement the interface.
Given we want to be able to add members to DbSet, we swapped to a base class approach where DbSet is a base class that you can directly mock or inherit.
Here are some links that show how to use DbSet rather than IDbSet:
https://msdn.microsoft.com/en-us/data/dn314429
https://msdn.microsoft.com/en-us/data/dn314431
From the Entity Framework Design Meeting Notes, on May 16, 2013:
The team recognized the potential for breaking changes:
The DbSet classes (generic and non-generic) inherit from a (generic or non-generic) IDbSet interface. IDbSet is intended only for creating test doubles, be these mocks or fakes.
However, in EF6 DbSet has changed in four ways that if reflected in equivalent changes for IDbSet would be breaking changes:
FindAsync added
AddRange/RemoveRange added
Local return type changed to DbLocalView (this change may be reverted anyway)
They discussed a bunch of potential changes in detail, but ultimately decided to avoid the breaking change, and to "make DbSet more mockable":
The decision was to make DbSet more mockable. However, we will not obsolete IDbSet because this would create work for those currently using IDbSet who don’t need to use the new members. We will add guidance to IDbSet indicating that using DbSet is the way to go for new code and, depending on feedback, we may choose to obsolete IDbSet in a future release.
And if you look at the code for IDbSet, they added comments to the top of the interface:
IDbSet was originally intended to allow creation of test doubles (mocks or fakes) for DbSet. However, this approach has issues in that adding new members to an interface breaks existing code that already implements the interface without the new members.
Therefore, starting with EF6, no new members will be added to this interface and it is recommended that DbSet be used as the base class for test doubles.
This is definitely not a bug and is done like this by design. It is hard to answer this type of question without being a developer on the .NET library but my guess is that they wanted to keep interfaces simple. Maybe someone on the .NET team will see this and chime in. Backwards compatibility issues will be tied to the interface/concrete implementation, which is also definitely a possibility in this scenario. However, this reasoning probably will not carry over to why IList/ICollection does not define those.
One argument is that by adding AddRange (as well as RemoveRange/InsertRange) to the interface, you are forcing the implementer to define those methods. Interfaces should be simple and easy to define. AddRange, etc methods should really only exist on concrete collections where you can see performance improvements. For example, a List can optimize its AddRange by properly increasing its internal capacity, etc. Where a simple loop over items and calling Add maybe be more costly (e.g. via an Extension method).
They probably do this for the same reason IList, ICollection, etc do not have an AddRange on the interface directly but do on the concrete implementations.
There is a workaround for this, and that is to abstract both the interface and the concrete class using your own interface/class. You can give your interface an AddRange and extend DBSet/implement your interface in another class. This may or may not work depending on how you are using IDBSet/DBSet in your code. Although, a little refactoring can make this work. Something like this --
public class MyDbSet<TEntity> : DbSet<TEntity>, IMyDbSet<TEntity> where TEntity : class
{
}
public interface IMyDbSet<TEntity> : IDbSet<TEntity> where TEntity : class
{
IEnumerable<TEntity> AddRange(IEnumerable<TEntity> items);
}
Now, you can just use IMyDbSet in your code. No need to implement AddRange as it is already implemented by extending DbSet. External methods that only accept IDbSet/DbSet should still accept MyDbSet/IMyDbSet.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
what is your preferred implementation style for a factory pattern? For example, consider a website where I want to use a factory pattern to save to 2+ external systems. This is my first impression for a clean implementation:
Create a class named ExternalSystemManagerFactory
In the constructor of this class pass in an enumeration to indicate the target external system. For example: ExternalSystemManager.System1 or ExternalSystemManager.System2
Create a property on this class named ExternalSystemManager of type IExternalSystemManager
The constructor would set this property value based on the constructor argument
Create a method stub on IExternalSystemManager named SaveToExternalSystem
Create 2 concrete classes for my external systems that implement IExternalSystemManager (EsmSystem1, EsmSystem2)
Then in my client class, I could save to ExternalSystem1 like this:
new ExternalSystemManagerFactory(ExternalSystemManager.System1).ExternalSystemManager.SaveToExternalSystem();
Does this seem like a reasonable implementation? Do you see any potential issues with this implementation? Is this a fairly common implementation style or is there a general trend towards a different implementation style?
In my opinion when it comes to patterns, it typically has to do with how it "feels" when you use it. If you are comfortable with accessing your data in the way you have written it, then by all means go for it. I'm a firm believer that there really isn't a perfect way to implement a pattern and I actually avoid them unless my code blatantly has a need and they emerge naturally. So my advice is...Don't force it, but if it feel good, then do it.
The approach that you describe is ok, if it is only about two implementations. If the number of external systems that you want to access increases, you'd always have to change
the enum
the switch statement in the constructor that chooses the concrete implementation.
In the abstract factory pattern that the Gang of Four describes, you'd get rid of the enum and implement it like this:
An abstract base class/interface for the factory.
An implementation of the factory for each concrete external system.
You create the concrete factory at one spot in your code and always access it through the interface.
An advantage of this implementation is that you can easily configure which factory to create instead of using a switch statement in your code. Besides that you wouldn't have to adjust the switch statement each time you connect a new external system, it also allows you to create implementations for new systems without touching the assembly of the factory at all.
Another approach you might want to consider if you have lots of dependencies you want to create is to use an Inversion of Control Container. You register the types that should be created for an interface at the beginning of your application and ask the IOC container if you need an instance or inject it in the constructors of the classes. There are several IOC containers available, e.g. Microsoft Unity, Ninject, AutoFac, .... This will save you lots of time if you have several or huge factories.
This question already has answers here:
Why would I want to use Interfaces? [closed]
(19 answers)
Closed 8 years ago.
I am working on learning C# in depth. I am mostly confused by the frequent implementation of interfaces. I always read that this class implements this interface. For instance, SqlConnection class implements IDbConnection. What is the benefit for developers in this case?
the interfacing is based on object-oriented principles, e.g. see SOLID. You should not rely on implementation of other classes you're working with - it should be sufficient for you to know only what they do and what they should return. A good example with the SqlConnection would be that you may be able to change the DB you are using quite simply (to e.g. MySQL or Oracle) by changing the implementation on just one place, providing that your code is correctly using the interfaces and propagating the instances.
An interface contains definitions for a group of related functionalities that a given type must implement (a sort of Method Signature Contract). It does not, however, guarantee the specific behavior of those implementations.
Interfaces are particularily useful as they allow the programmer to include behavior from multiple sources in programming languages that do not support multiple inheritance of classes like C#.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
A question was raised in a discussion I had around whether an interface method should return a Custom object vs a primitive type.
e.g.
public interface IFoo
{
bool SomeMethod();
}
vs
public interface IFoo
{
MyFooObj SomeMethod();
}
Where MyFooObj is:
public class MyFooObj
{
bool SomeProp{get;set;}
}
The argument being that you can easily add properties to the object in the future without needing to change the interface contract.
I am unsure what the standard guidelines on this are?
IMHO Changing the MyFooObj is the same as changing/adding methods to the IFoo Interface - so no I don't think it's a good idea add just another abstraction - remember YAGNI
My standard response is - YAGNI.
You can always change things if it turns out that way, in particular if you control the full source of the application and how the interface is used.
Wrapping a boolean just in order to forecast the future is only adding complication and additional layers of abstraction when they are not currently needed.
If you are using DDD and specific modelling techniques in your codebase, is can make sense to have such aliases to booleans, if they are meaningful in your domain (but I can't see this being the case for a single boolean value).
I don't see the point of encapsulating primitive types in a custom object.
If you change the definition of this custom object, then you actually change the contract because the function doesn't return the same thing.
I think it's again an over-engineered "pattern".
There are no general guidelines regarding this.
As you pointed out, if you have semantics around the return type that you think strongly believe may change or may need to be updated in the future it may be better to return the complex type.
But the reality is that in most circumstances it is better to keep things simple and return the primitive type.
That depends somewhat on what you like. My opinion, that in your sample case, I would stick with the simple bool in the interface definition for those reasons:
it is the simplest to read possibility
no one looks for methods that aren't available
IMHO, an object makes sense only when a certain amount of complexity/grouping is required as a result.
If its not required to begin with you should not wrap it changing what is returned inside the object is simply the same as changing the interface which breaks rule number one of programming with interfaces.
Its right up there with designing for extension, YAGNI (you ain't gonna need it).
As a side note I got told off for stuff like this early in my career.
If you ever need to return something more than a boolean, it is extremely likely that you are going to modify other parts of the interface as well. Do not make things more complex than they need to be: simplicity is prerequisite of reliability.
In addition to the other answers, adding a new field to a custom class is technically still a potential breaking change to the interface's consumers. Link
Just thought I'd mention that if MyFooObj is in an assembly which is strong named, you update it, its version gets updated - old clients will immediately break (e.g. InvalidCastException) due to a version mismatch (it won't attempt a partial bind due to strong nameness) unless they recompile with the new version. You've still changed the interface contract. So best to keep things simple, return the primative type and declare your change of contract more explicitly.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I have been working in C# for quite some time but come around this perennial question with colleagues now and then.
The question is: In an inherited class set -- when calling a method should we use keywords 'base.methodname and this.methodname'... irrespective of whether it is a overridden method or not?
My answer is: YES -- its a good practice -use it because that is why those were created for.
Detailed explanation: Moreover the code is likely to undergo changes in terms of logic and maybe some IF-ELSE like conditions may come-in at a later date. So at that time, the developer has to be compelled to revisit each line of code and ensure that he/she makes the right choice of which method is being called --- base.methodname() or this.methodname() ELSE the .NET framework will call the DEFAULT (i think its base.methodname()) and the entire logic can go for a toss.
What do other C# programmers think about it?
Whether or not you use "this." is a matter of opinion. Some like it because it is clear that you are calling something class level, others feel it is redundant noise.
As for base - in my opinion you should only explicitly say "base." if you want to call the base method explicitly and not an overridden method in the current class. Quite often the only place you should even see it is in the overridden method itself.
Don't call base just because it is the implementation in the base class that will be called. It is not meant to be a way of saying "I know the actual implementation is in the base class", it is meant to be a way of saying "specifically do not call the implementation in this class, call the base one". To use it in any other way partly defeats the point of inheritance.
If you are sure that you will always use the method in base class, you can use base.MyMethod.
But be aware of this:
Imagine that you have a method called "GetPrice" in base class and you start using base.GetPrice all over your inherited class (PromoClass). After 3 months someone asks to change the way that price is calculated in Promotions (PromoClass), you (or the new developer) will override or new the method and test it... wait, don't work :|. Because you are always calling for the method in base class. So it will still call the method in base and you need to change all calls in the class.
It's an example of course. If that is standard in your company everyone should know that he should change all over the class the call of that method, if not, be careful.
I prefer to use "base." to use base methods but I normally ignore the "this.".
I concur with #Holstebroe and #Bruno Costa. When you are explicitly calling base.Method every time, you are effectively cutting off the potential for polymorphism, and that's one of the basic reasons to use inheritance in the first place.
I think it smells like bad class design if you in any way could be in doubt whether you are calling a method in a class or a base class.
It is hard for me to find any good examples that would justify explicitly calling overridden base class methods, expect if deriving from legacy or third party classes.
Personally I almost never use virtual methods. You can almost always make a better design with interfaces and abstract methods.
When using base calls it is because you want to extend the functionality of the base method, so you call the base method in the overriding method. Any other usage of base is in my opinion wrong in every way. Also, before overriding a virtual method and calling base you should consider if the extension could be implemented otherwise. For example, if your base method called an abstract method or an interface method that you could either implement or inject in the derived class.
The few times I have used virtual methods are when leaving "blank" methods in a general purpose base class. The blank methods (like InitializeThread() in a thread encapsulation) allows me to optionally extend the base class, but I would never write code in the base methods and never call base.
Calling base is just wrong!