I know from this question that extension methods can only operate on class instances, not the static class itself. This means I can't extend useful static classes like Convert and Math.
What I want to know is, why is this the case? From the link above, there are some suggestions on how the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?
For example, here's a rationale behind why there is no built-in LINQ ForEach<T> extension for IEnumerable<T>.
the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?
There's no technical reason, and no philosophical reason. However, as I often point out, I don't have to provide a justification for not doing a feature. Features aren't cheap; they are extremely expensive and they must not only justify their own cost, they must justify the opportunity cost of not doing the hundred other features we could have done with that budget. We must justify the cost of features to our stakeholders, but we need not justify saving time and effort by not implementing features that don't meet our bar.
In particular, the proposed feature does nothing for LINQ; extension methods were added to make LINQ work. Anything that didn't make LINQ work was very hard to get into C# 3.0; we had a lot of work on the schedule and not much time to do it in. (I was surprised that automatic properties made it in.) Cutting an unnecessary feature before even designing it saved a lot of time and effort that was spent on other things that do make LINQ work.
In short: the suggested feature has never met our bar for net benefit over cost, and we've always had more important features to spend our limited time and effort on.
After reading through the answers, as well as some related questions, I've assembled my understanding of the issue here.
How extension methods work
First, it's important to realize that extensions are just syntactic sugar for static methods.
// Say you have an extension method that looks like this:
class Extensions
{
public static void Extend(this SomeClass foo) {}
}
// Here's how you call it
SomeClass myClass;
myClass.Extend();
// The compiler converts it to this:
Extensions.Extend(myClass);
The method doesn't actually become part of the class. This is why you can't access private members from an extension method. Extension methods change C# syntax only, and do not violate the concept of OOP accessibility. In fact, if you write an extension method and a normal static method that do the same thing, then decompile the MSIL, they are exactly the same.
Why extension methods exist
So if they don't add actual functionality, why have extension methods at all? The answer is LINQ:
// LINQ makes this easy to read
array.Where(i => i&1 == 0).Select(i => i*i);
// Without extension methods, we would have to do it like this
Enumerable.Select(Enumerable.Where(array, i => i&1 == 0), i => i*i);
In a way, all of LINQ is just syntactic sugar, since everything it can do could be written in a clunky, non LINQy way. Obviously the C# team felt that the readability gained by LINQ was worth it, but it begs the question, "why did they stop there?"
Why not other extension types?
Eric Lippert, one of the C# compiler devs, described in a blog post that a huge part of C# 3 was creating all of the constructs necessary for LINQ: "implicitly typed locals, anonymous types, lambda expressions, extension methods, object and collection initializers, query comprehensions, expression trees, [and] improved method type inference." Because the C# team was the most resource-limited team for the 2008 .NET release, additional types of extensions that weren't strictly necessary for LINQ were not included.
The team did consider implementing extension properties in C# 4, and actually wrote a working prototype, but it was dropped when they discovered it would not enable the WPF team as implemented (which was one of the motivators for the feature). Eric Lipper later said they they did consider extension methods for static classes, but could not justify the real-world benefits against the costs of implementation, testing, and maintenance.
A workaround
It is possible to write an extension method that gets close:
public static TResult DoSomething<TType, TResult>(this TType #class)
{
// access static methods with System.Reflection
return default(TResult);
}
// This works, but poorly
typeof(Math).DoSomething();
typeof(Convert).DoSomething();
But it's pretty ugly. It requires reflection, and can't support any kind of intelligent typing, since any Type can call it and that's likely not the intended functionality.
I believe the answer for your question is because it doesn't make any sense to extend with static methods. Main reason behind introducing Extension methods is not extending class which you do not own. Main reason is that it will allow reduce methods nesting in examples like these:
Enumerable.Select(Enumerable.Where(arr, i => i & 1 == 0), i => i*i); // not the best thing I ever read
arr.Where(i => i&1 == 0).Select(i => i*i); // wow, I see! These are squares for odd numbers
That is why there is no such point to have extension methods for static classes.
Extension methods operate on objects, not classes. If you want an extension method to operate on a class, I suppose you could do this:
public static T DoSomething<T>(this T #class)
where T:Type
{
// access static methods via reflection...
return #class;
}
Static extensions are possible in F# :
type Platform =
| Win32
| X64
override this.ToString() =
match FSharpValue.GetUnionFields(this, typeof<Platform>) with
| case, _ -> case.Name.Replace('X', 'x')
type Environment with
static member Platform =
if System.IntPtr.Size = 8 then Platform.X64 else Platform.Win32
Well its not only about not implemented, but it will cause confusion of where the method belongs to? Static extensions were introduced because linq came in later version and only to support linq in easy to code way, static extensions are useful.
Static extensions are useful only to make code more readable. It has no significance at runtime or compile time.
Related
As a premise one of a key difference of FP design about reusable libraries (for what I'm learning), is that these are more data-centric that corresponding OO (in general).
This seems confirmed also from emerging techniques like TFD (Type-First-Development), well explained by Tomas Petricek in this blog post.
Nowadays language are multi-paradigm and the same Petricek in its book explains various functional techniques usable from C#.
What I'm interested here and, hence the question, is how to properly partition code.
So I've defined library data structures, using the equivalent of discriminated unions (as shown in Petricek book), and I project to use them with immutable lists and/or tuples according to the domain logic of mine requirements.
Where do I place operations (methods ... functions) that acts on data structures?
If I want define an high-order function that use a function value embodied in a standard delegates Func<T1...TResult>, where do I place it?
Common sense says me to group these methods in static classes, but I'd like a confirmation from people that already wrote functional libs in C#.
Assuming that this is correct and I've an high-order function like this:
static class AnimalTopology {
IEnumerable<Animal> ListVertebrated(Func<Skeleton, bool> selector) {
// remainder omitted
}
}
If choosing vertebrated animal has N particular cases that I want to expose in the library, what's the more correct way to expose them.
static class VertebratedSelectorsA {
// this is compatible with "Func<Skeleton, bool> selector"
static bool Algorithm1(Skeleton s) {
//...
}
}
or
static class VertebratedSelectorsB {
// this method creates the function for later application
static Func<Skeleton, bool> CreateAlgorithm1Selector(Skeleton s) {
// ...
}
}
Any indication will be very appreciated.
EDIT:
I want to quote two phrases from T. Petricek, Real World Functional Programming foreword by Mads Torgersen:
[...] You can use functional programming techniques in C# to great benefit,
though it is easier and more natural to do so in F#.
[...]
Functional programming is a state of mind. [...]
EDIT-2:
I feel there's a necessity to further clarify the question. The functional mentioned in the title strictly relates to Functional Programming; I'm not asking the more functional way of grouping methods, in the sense of more logic way or the the way that make more sense in general.
This implies that the implementation will try to follow as more as possible founding concepts of FP summarized by NOOO manifesto and quoted here for convenience and clarity:
Functions and Types over classes
Purity over mutability
Composition over inheritance
Higher-order functions over method dispatch
Options over nulls
The question is around how to layout a C# library wrote following FP concepts, so (for example) it's absolutely not an option putting methods inside data structure; because this is a founding Object-Oriented paradigm.
EDIT-3:
Also if the question got response (and various comments), I don't want give the wrong impression that there has been said that one programming paradigm is superior than another.
As before I'll mention an authority on FP, Don Syme, in its book Expert F# 3.0 (ch.20 - Designing F# Libraries - pg.565):
[...] It's a common misconception that the functional and OO programming methodologies compete; in fact, they're largely orthogonal. [...]
Note: If you want a shorter, more-to-the-point answer, see my other answer. I am aware that this one here might seem to ramble & go on forever & talk past your issue, but perhaps it will give you a few ideas.
It is difficult to answer your question without knowing the exact relationship between Animal and Skeleton. I will make a recommendation about this relationship in the second half of my answer, but before I do that, I will simply go along with what I see in your post.
First I will try to infer a few things from your code:
static class AnimalTopology
{
// Note: I made this function `static`... or did you omit the keyword on purpose?
static IEnumerable<Animal> ListVertebrated(Func<Skeleton, bool> selector)
{
…
}
}
If you have designed that function according to functional principles, it should have no side-effects. That is, its output relies only on its arguments. (And in a semi-object-oriented setting, perhaps on other static members of AnimalTopology; but since you didn't show any, let us ignore that possibility.)
If the function is indeed side-effect-free (and does not access static members of AnimalTopology), then the function's type signature suggests that it is possible to derive an Animal from a Skeleton, because it accepts something that acts on Skeletons and returns Animals.
If this is also true, then let me assume the following for the sake of being able to give an answer:
class Skeleton
{
…
public Animal Animal { get { … } } // Skeletons have animals!? We'll get to that.
}
Now it is obvious that your function is impossible to implement, since it could derive Animals from Skeletons, but it doesn't receive any Skeleton at all; it only receives a predicate function that acts on a Skeleton. (You could fix this by adding a second parameter of type Func<IEnumerable<Skeleton>> getSkeletons, but...)
In my opinion, something like the following would make more sense:
static IEnumerable<Animal> GetVertebrates(this IEnumerable<Skeleton> skeletons,
Func<Skeleton, bool> isVertebrate)
{
return skeletons
.Where(isVertebrate)
.Select(s => s.Animal);
}
Now, one might wonder why you are guessing animals from their skeletons; and isn't the bool property "is vertebrate" an inherent property of an animal (or skeleton)? Are there really several ways to decide on this?
I would suggest the following:
class Animal
{
Skeleton Skeleton { get; } // not only vertebrates have skeletons!
}
class Vertebrate : Animal { … } // vertebrates are a kind of animal
static class AnimalsExtensions
{
static IEnumerable<Vertebrate> ThatAreVertebrates(this IEnumerable<Animal> animals)
{
return animals.OfType<Vertebrate>();
}
}
Please note the use of extension methods above. Here's an example how to use it:
List<Animal> animals = …;
IEnumerable<Vertebrate> vertebrates = animals.ThatAreVertebrates();
Now suppose your extension method did more complex work. In that case, it might be a good idea to put it inside its own designated "algorithm type":
interface IVertebrateSelectionAlgorithm
{
IEnumerable<Vertebrate> GetVertebrates(IEnumerable<Animal> animals);
}
This has the advantage that it can be set up / parameterized e.g. via a class constructor; and you could split up the algorithm into several methods that all reside in the same class (but are all private except for GetVertebrates.)
Of course you can do the same kind of parameterization with functional closures, but in my experience that quickly gets messy in a C# setting. Here, classes are a good means to group a set of functions together as one logical entity.
Where do I place operations (methods ... functions) that acts on data structures?
I see four common approaches (in no particular order):
Put the functions inside the data structures. (This is the object-oriented "method" approach. It is suitable when a function acts only on an instance of that type. It is perhaps less appropriate e.g. when a function "draws together" several objects of different types, and spits out an object of yet another type. In this case, I would...)
Put the functions inside their own designated "algorithm classes". (This seems reasonable when the functions do much or complex work, or need to be parameterized/configured, or where you might want to split the algorithm into several functions that you can then logically "group" together by putting them in a class type.)
Turn the functions into lambdas (a.k.a. anonymous delegates, closures, etc.). (This works well if they're small and you only need them in one specific place; the code won't be easily reusable in a different place.)
Put the functions in a static class and make them extension methods. (That's how LINQ to Objects works. It is a hybrid functional & object-oriented approach. It takes some extra care to get the discoverability / namespacing issue right. Many people will think this approach breaks "encapsulation" when taken too far. For a counter-argument, read the excellent C++ article "How Non-Member Functions Improve Encapsulation"; substitute "extension method" for "non-member friend function".)
Note: I could go into each of these in more detail if people want, but before I do that, I'll wait and see what kind of feedback this answer receives.
I have a piece of code like the following:
public class ActivityHelper
{
public void SetDate(IList<Activity> anActivityList)
{
foreach(Activity current in anActivityList)
{
current.Date = DateTime.Now;
}
}
//More methods, properties, fields, etc...
}
This could easily be converted to an extension method. For example:
public static void SetDate(this IList<Activity> aList)
{
foreach(Activity current in anActivityList)
{
current.Date = DateTime.Now;
}
}
The original function doesn't use any instance specific data or methods from the ActivityHelper class which makes it seem like it is in the incorrect place. Is this the correct time to write an extension method? What are the correct scenarios in which to create extension methods?
Brad Adams has written about extension method design guidelines:
CONSIDER using extension methods in any of the following scenarios:
To provide helper functionality relevant to every implementation of an interface, if said functionality can be written in terms of the core interface. This is because concrete implementations cannot otherwise be assigned to interfaces. For example, the LINQ to Objects operators are implemented as extension methods for all IEnumerable types. Thus, any IEnumerable<> implementation is automatically LINQ-enabled.
When an instance method would introduce a dependency on some type, but such a dependency would break dependency management rules. For example, a dependency from String to System.Uri is probably not desirable, and so String.ToUri() instance method returning System.Uri would be the wrong design from a dependency management perspective. A static extension method Uri.ToUri(this string str) returning System.Uri would be a much better design.
I think Extension methods are only appropriate if there is a compelling reason to make the method an extension method.
If the type is one you do not control, and the method should appear to be integral to the type, or if there is a compelling reason to not put the method directly on the type (such as creating an unwanted dependency) then an extension method could be appropriate.
Personally, if the expectation of the user of your API will already be to use the "ActivityHelper" class when working with collections of Activities, then I would probably not create an extension method for this. A standard, non-extension method will actually be a simpler API, since it's easily understood and discoverable. Extension methods are tricky from a usage standpoint - you're calling a method that "looks like" it exists somewhere other than where it actually exists. While this can simplify syntax, it reduces maintainability and discoverability.
In my experience extension methods work best when they:
Don't have side-effects (most of the extension methods my team wrote that have side-effects, we ended up removing because they caused more problems than they helped)
Offer functionality that applies to every possible instance or value of the type they're extending. (Again citing an example from my team, string.NormalizeUrl() is not appropriate because not all strings are even URLs anyway)
Well i usually create extension methods to help me write codes which have a smooth flow. Its generally depends upon the method you are creating.
If you feel that the method should have already been in framework and is too general then its okay to create an extension method for that.
But you need to first analyze that the class you are extending will always will be in state that your extension method can handle.
For Guidelines here to Brad's Article
http://blogs.msdn.com/b/brada/archive/2009/01/12/framework-design-guidelines-extension-methods.aspx
In essence, Extension Methods provide a more fluent style syntax for Helper methods. This translates into the ability to seemingly add functionality to types or all implementations of interfaces.
However, I generally steer away from declaring Extension Methods with a void returntype, as I feel the usefulness of this fluent style syntax, which allows you to compose statements, is negated when the method in question doesn't return anything.
However, I guess it can be handy to have your methods picked up by IntelliSense... :-)
Before you start pointing me to duplicates just know that I have read nearly all the posts on SO about extension methods. I am just trying to play devil's advocate for a minute to consider the alternative to my working opinion.
Recently I was working on a project and a need came up for a method to be a base of an interface. So I suggested we write an extension method and it was shot down. Saying it added complexity and harder to debug.
I of course argued and got on SO to find all the wonderful posts that show the many reasons why to use extension methods. Not to forget that a lot of the .net framework uses them. We eventually did not use it as I was overruled by the team.
But then it got me thinking, are there times when an extension method could be used but shouldn't be?
I really couldn't think of any but thought I would post here and see if anyone could think of any other reasons why they shouldn't be used.
Any time you have a function which is "generally applicable" to an object of a certain type, regardless of its state, an extension method is a good choice.
For example, today I added two new extension methods to our codebase:
public static XElement ToXElement(this XmlElement element) { }
public static XmlElement ToXmlElement(this XElement element) { }
Both of these are, generally speaking, valid on the types they extend regardless of the state of the instance or where we are using it.
If your method does not meet that criteria, it should probably be moved to a helper method closer to the context where the particular case is always true or easily checked.
For example, a developer recently nominated this to be an extension method:
public static bool ParseYesNoBool(this string input) { }
There are two problems here: first, this will appear on all strings in the application, even though the number of strings which might ever be candidates for this case are very small. So we've broken the first rule, in that it is not useful regardless of state. Similarly, but second, the consumer of this functionality is limited to a single parser for one particular connector to an external system. So promoting implementation-specific functionality into the general-use namespace makes no sense. This was downgraded to a helper method in the parser.
As far as readability and debugging, that is just incorrect for a developer of any reasonable skill level.
In general if you control the source-code for the assembly and adding the method does not cause any breaking changes to existing code (which would have been the case if for example LINQ had not been implemented via extension methods) it is better to just add a normal method.
This discussion of the Framework Design Guildelines section on extension methods contains some good advice. I think the relevant portion for your scenario is:
To provide helper functionality relevant to every implementation of an interface, if said functionality can be written in terms of the core interface.
If your proposed usage did not pass that test then it should have been shot down.
I would say you should avoid them when "they do not make the intend of the code more clear". Of course, whether or not some code (or codeing style) is "more clear" varying widely between people, so that's pretty much useless. (I had one boss who said we shoudl avoid using interfaces because they made the code "too complex and hard to understand")
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
Any time you break the intent and design for the feature I would recommend reconsidering the use of an extension method. I see a few situations when you don't want to use an Extension method:
1) Changing the Object Model to allow for an Extension method: The class you want to create an extension on is an abstract class. This is going to require you either make each inherited class it's own version of the extension or remove abstract from the class. Either way, you are changing the object model in order to use an extension method.
2) Forgetting the Decorator Pattern: The number of extension methods you create for a class exceeds three. I find it is easier to organize/communicate and maintain the domain/object model with decorated objects than with extended objects. However, the opposite is also true: If a decorated object has less than four methods, I find a lot of almost "empty" objects in my project.
3) Private functions: Private functions are meant to modify(create, delete, etc..) the object and extension methods are meant to use the type, much like a struct would. If you find the extension is being assigned to another instance of the type then it probably should not be in an extension.
We are currently discussing whether Extension methods in .NET are bad or not. Or under what circumstances Extension methods can introduce hard to find bugs or in any other way behave unexpectedly.
We came up with:
Writing an extension method for types that are not under your control (e.g. extending DirectoryInfo with GetTotalSize(), etc...) is bad, because the owner of the API could introduce a method that hides our extension - and might have different edge cases. For example testing for null in an extension method will automatically translate into a NullReferenceException if the extension method is no longer used due to hiding.
Question:
Are there any other dangerous situations than "hiding" that we are not thinking of?
Edit:
Another very dangerous situation.
Suppose you have an extension method:
namespace Example.ExtensionMethods
{
public static class Extension
{
public static int Conflict(this TestMe obj)
{
return -1;
}
}
}
And use it:
namespace Example.ExtensionMethods.Conflict.Test
{
[TestFixture]
public class ConflictExtensionTest
{
[Test]
public void ConflictTest()
{
TestMe me = new TestMe();
int result = me.Conflict();
Assert.That(result, Is.EqualTo(-1));
}
}
}
Notice that the namespace where you use it is longer.
Now you reference a dll with this:
namespace Example.ExtensionMethods.Conflict
{
public static class ConflictExtension
{
public static int Conflict(this TestMe obj)
{
return 1;
}
}
}
And your Test will fail! It will compile without a compiler error. It will simply fail. Without you even having to specify "using Example.ExtensionMethods.Conflict". The compiler will walk the namespace name and find Example.ExtensionMethods.Conflict.ConflictExtension before Example.ExtensionMethods.Extension and will use that without ever complaining about ambiguous extension methods. Oh the horror!
Some curiosities:
extension methods might be called on null instances; this might be confusing (but sometimes useful)
the "hiding" issue is a biggie if they have different intent
equally, you might get a different extension method with the same name from 2 different namespaces; if you only have one of the two namespaces, this could lead to inconsistent behaviour (depending on which)...
...but if somebody adds a similar (same signature) extension method in a second namespace that your code uses, it will break at compile time (ambiguous)
(edit) And of course, there is the "Nullable<T>/new()" bomb (see here)...
I disagree, the whole point of extension methods is to add your members to black boxed classes. Like everything else there are pitfalls, you must be mindful in naming, implementation and understand the pecking order of the methods.
One breakage we've just found in the MoreLINQ project: if you write a generic extension method, it's impossible to make sure it will work with all types. We've got a method with this signature:
public static IEnumerable<T> Concat<T>(this T head, IEnumerable<T> tail)
You can't use that with:
"foo".Concat(new [] { "tail" });
because of the string.Concat method...
I've used Ruby on Rails for almost as long as I've used C#. Ruby allows you to do something similar to the new extension methods. There are, of course, potential problems if someone named the method the same, but the advantages of being able to add methods to a closed class far outweigh the potential dissadvantage (which would probably be caused by bad design or poor planning).
One thing you can do to make sure extension methods don't conflict with other methods (extension or otherwise) is to use FxCop with rules such as Prevent Duplicate Extension Method Signatures.
First of all I believe your wording is a bit misleading. I take it you're talking about "types" and not "objects".
Secondly, the big advantage of extension methods is that you can add features to type you don't control. If you control the type, why not just modify the type instead of relying on extension methods?
We took the attitude in my team that Extension Methods are so useful that you can't realistically ban them, but so dangerous (principally because of the hiding issue) that you have to be a bit cautious. So we decided that all Extension Method names have to be prefixed with X (so we have a bunch of XInit...() methods to initialise controls in useful ways, for instance). That way a) the likelihood of a naming collision is reduced and b) the programmer knows he is using an Extension Method and not a class method.
What .Net calls extension methods are also a limited form a MonkeyPatching (try to ignore the php rant in there).
That should give you some material for your discussion.
I recently asked this question:
Compiler error referencing custom C# extension method
Marc Gravell answer was perfect and it solved my problem. But it gave me something to think about...
If and Extension method must be placed on a Static Class and the method itself must be static, why can't we create a static Extension method?
I understand that the parameter marked as "this" will be used to allow access to an instance of the object we are extending. What I do not understand is why can't a method be created to be static... it just seems to me that this is a senseless limitation...
My question is: Why can't we create an extension method that will work as a static Method?
I expect the real answer is simply: there wasn't a good use-case. For instances, the advantage is that it enables a fluent-API over existing types (that don't themselves provide the logic) - i.e.
var foo = data.Where(x=>x.IsActive).OrderBy(x=>x.Price).First();
which enables LINQ:
var foo = (from x in data
where x.IsActive
order by x.Price
select x).First();
With static methods, this simply isn't an issue, so there is no justification; just use the static method on the second type.
As it is, extension methods are not properly object orientated - they are a pragmatic abuse to make life easier at the expense of purity. There was no reason to dilute static methods in the same way.
Because that feature doesn't exist in C#.
As a workaround, static methods can be implemented in another class and called through that class to provide the added functionality.
For example, XNA has a MathHelper class which ideally would have been static extensions to the Math class.
The community is asking if we think it's a good idea for C# 4.0
My thinking would be for compatibility - if you suddenly made all static methods extension methods with the need for the this operator you could inadvertently break code which now is overriding a normal method with an extension method.
The this parameter allows control and thus doesn't break compatibility.
Just an idea though.
First of all you would have to add yet another syntax to indicate you want to extend the static methods of the existing type. When extending syntax you really need a very good reason to do so.
Lets imagine I have a class called MyExts which allow me to add extension methods to MyClass. Why would:-
MyClass.DoSomethingExtra();
be better than
MyExts.DoSomethingExtra();
?