As Anders pointed out in his Channel9 demo, Extension Methods in C# 3.0 really make Linq possible. After drilling into Extension Methods and wanting to not like them, I must ask: what were the alternatives The example that Ian Griffith's gives of some 3rd party developer quietly including something like:
namespace System
{
public static class Evil
{
public static void Print(this object s)
{
Console.WriteLine(s);
}
}
}
Seems horrifying to say the least. I have to ask what the alternatives were.
Why not maybe :
namespace MyNameSpace
{
public class extend System.Array
{
public System.Array Slice();
}
}
The concept would be phlosophically similar to the new partial capability in C# 2.0. Just looking for some general comments here. I am worried (possibly needlessly) that the "killerness" of Linq might come at the cost of non-determinism becasue of the use of statics.

Extension Methods: Static Electricity?
rsedor
~DigBoy~
SteelX
I thought that the scope was namespace not assembly. In other words, by adding
using System.Query;
I get the extensions method defined within the namespace System.Query.
Russ V.
Maybe there should be an alternative to 'using'
Something like:
using extensions System.Query;
This would avoid 'accidental' use of extensions.
dan6546546
The extension methods are defined as static, yes, but in practice they're syntactically non-static (that is, they're called as if they were instance methods). So a property would be handled identically.
An extension method defined as
public static class MyExtensions {
public static int GetValue(this Foo self) {
return self.something;
}
}
and called as
Foo obj = new Foo();
int x = obj.GetValue();
is compiled as if it was
int x = MyExtensions.GetValue(obj);
It's static only with respect to "MyExtensions". In use, though, it's compiled against the instance obj, making it "look" like an instance method. Since it's external to obj, it can only access public members, so encapsulation isn't broken. What we'd like in a property is to make it
public static class MyExtensions {
public static int Value(this Foo self) {
get { return self.something; }
}
}
int x = obj.Value;
which is only a minor change.
smhaig
In order for them to be able to add properties to a type, wouldn't the extensions have to change from Static members to Instance members I don't see the utility in having a Static 'property' so to speak.
If that's the case, how would this be implemented What would the ramifications be in terms of object encapsulation Would Instance Extension Members be able to modify protected or private fields of an object, or call protected or private methods
As I understand it, when C# code is compiled that makes use of Extension methods, the compiler just translates the extension method into the applicable Static method call. Is this view correct The compiler doesn't do any weird tricks at the moment, does it And if not, how will that change if you do move to Instance Extensions
I can think of a use for an Instance Extension Property right now, matter of fact. I recall in my VB 6.0 days that almost all controls had a 'Tag' property of type Object that is kinda missing from most objects nowadays. It'd be great to be able to extend objects to include such a property.
Sorry for so many questions. :P Very curious, I am, yes...
Louis Phillipee
If you want to use a specific version of an extension where multiple are available you can either use type specificity (IEnumerable<int> is more specific than IEnumerable<T> therefor is used) or explicitly call the static class that defines the extensions:
using System.Query;
using MyQuery;
...
var q = list.Where(...);
var q = Sequence.Where(list, ...);
var q = MySequence.Where(list, ...);
UncleB
rinku
extend with <Namespace1> // extend all applicable using Namespace1
extend with <Type1> // extend all applicable using Type1
extend with <Type2>.<Method> // extend all applicable with one particular Method
extend <TypeX> with <Namespace2> // extend TypeX using Namespace
extend <TypeX> with <Type3> // extend TypeX using another Type
extend <TypeX> with <Type4>.<Method> // extend TypeX with one particular Method
... because sometimes you want to use your own method to extend a 3rd party Type, and you want to manage conflicts with other extensions.
Helder Rodrigues
I don't see the horror in the allegedly Evil class. WriteLine accepts object, and in fact is used quite often. Defining a Print() method applicable to object, while gratuitous, doesn't raise any technical alarms for me. Where's the non-determinism Everything is resolvable, and as with generics a method so defined isn't exercising APIs it wouldn't otherwise have access to, so even security is maintained.
The only problem I have at the moment is that there's no simple way to selectively use a single extension method from a set of methods defined in an assembly.
This whole extension method mechanism has been used in other languages, and well, for some time. I don't enjoy having to sprinkle explicit static statements all over the source, but I certainly don't see the problem with the methods *as compiled* being static.
microuser
So in my example of an Extension member that might add a 'tag' property to an object, how would I implement this currently
I understand that I can't add a property - but I can add "get" and "set" methods that kind of emulate one. Knowing that the Extensions are static, how would I implement this against all instances of a particular object
Assuming the Tag "property" has a signature like this:
static int GetTag(this object obj);
static void SetTag(this object obj, object tag);
RobAus
Well, let's say you have this class
public class Foo {
public int Number;
}
you could add these pseudo-properties
public static class MyExtensions {
public static int GetDoubleNumber(this Foo self) {
return self.Number * 2;
}
public static void SetDoubleNumber(this Foo self, int value) {
self.Number = value / 2;
}
}
and then say
Foo myFoo = new Foo();
myFoo.SetDoubleNumber(100); // myFoo.Number is now 50
int x = myFoo.GetDoubleNumber(); // x is now 100
Note that in this example I'm doing some trivial math in the pseudo-properties. That's because, since "Number" is already a public member of Foo, it's kind of pointless to wrap its access in a property unless you're doing some other work to make it worthwhile.
If you're really interested in "attaching" a property to an object (that is, making it seem like it has a member it doesn't intrinsically have), you'll have to store the value of that property yourself:
public static class MyFakeProvider {
private static Dictionary<Foo, string> propertyCache;
private static MyFakeProvider() {
propertyCache = new Dictionary<Foo, string>();
}
public static string GetName(this Foo self) {
if(propertyCache.HasKey(self) {
return propertyCache[self];
} else {
return null;
}
}
public static void SetName(this Foo self, string value) {
propertyCache[self] = value;
}
}
You'll therefore have to deal with the problems of stray object references (your cache will carry a reference to every "tagged" object you touch, and therefore will keep them from being garbage-collected) and such, but you get the idea.
David L. Price
sbailey
My personal desire would be to just give up and implement extension keywords:
public void FooMethod(int x) extends Bar bar { doSomething(bar, x); } public string TextRot13 extends Bar bar { get { return Rot13(bar.Text); } set { bar.Text = Rot13(value); } }