Azurewrath

Hi all,

While I was trying to implement my own extension methods, I realized most of what I need is included out of the box. That's really neat. I was crying to have these. But ironically I am asking why Smile

I mean when I browse them through intellisense, it says (extension). What I want to know is: why they are implemented as extension methods and not as standard methods

The method in this case is, List<int>.Max()





Thanks,
Aw


Re: Visual C# 2008 (Pre-release) New Extension Methods

Genevieve Orchard - MSFT

Hi Aw,

LINQ (language integrated query) introduces a set of "standard query operator" methods, like Max(), as extension methods. As you may have noticed, Max() and the other standard query operators are available not just on List<T>, but also on arrays, dictionaries, hash sets, and anything else that implements IEnumerable<T>. If these methods had been introduced as declared instance methods, each IEnumerable<T> type's class definition would have had to be changed. Instead, as extension methods, these methods are defined in one place only (the System.Linq.Enumerable type). The List<T> class definition was not touched. The cool part is that IntelliSense can still help to show you which extension methods are available on a type.

Another advantage of having the standard query operators defined as extension methods is that you can define your own IEnumerable<T> type and it will automatically gain access to all the methods such as Max(), Average(), OrderBy(), etc., saving you the work of implementing them yourself.

If a user does not want to make these or other extension methods available on a type, they can do this by not importing the namespace where the extension methods are defined.

I hope that answers your question.

Genevieve Orchard

C# Documentation Team






Re: Visual C# 2008 (Pre-release) New Extension Methods

Azurewrath

Great reply! Thanks alot.

So I have a few questions:

1. It's good that methods like Max exists for collections, but shouldn't they not be visible for string, etc collections I tried it works, but what does it do

2. When you said:

"If these methods had been introduced as declared instance methods, each IEnumerable<T> type's class definition would have had to be changed."

did you mean that these methods would have been declared inside the interface, which would arise the need to update all classes that implements this interface

3. When you said you can exclude these extension methods from your custom data type, did you mean compiling it without these namespaces, as in a Vector3 class, which in it's code will not include these codes and therefore they will not inherit these extension methods

4. Lastly what if you want some of these extension methods for your custom type but not all




Thanks alot again for replying,
Aw




Re: Visual C# 2008 (Pre-release) New Extension Methods

Genevieve Orchard - MSFT

  1. It's good that methods like Max exists for collections, but shouldn't they not be visible for string, etc collections I tried it works, but what does it do

There has been some debate about whether the standard query operators should show up in IntelliSense on string types, because it makes the IntelliSense list really long. The query operators can be useful when working with strings though, for example you could count the occurrences of the character "e".

2. When you said:

"If these methods had been introduced as declared instance methods, each IEnumerable<T> type's class definition would have had to be changed."

did you mean that these methods would have been declared inside the interface, which would arise the need to update all classes that implements this interface

That's not exactly what I meant, but that's another way of looking at it. I didn't mean that the interface would necessarily change, but that in order to create the same level of functionality that exists with these methods defined as extension methods, each class that implements IEnumerable<T> would have to change to define each and every standard query operator.

3. When you said you can exclude these extension methods from your custom data type, did you mean compiling it without these namespaces, as in a Vector3 class, which in it's code will not include these codes and therefore they will not inherit these extension methods

It's not as complex as that. Extension methods don't get inherited by the types that they extend. They are simply calls to static methods, but they have syntactic sugar that enables them to be called with instance-method syntax. An extension method call is compiled into a call to a static method on the type where it is defined. For example, myList.Max() is translated into System.Linq.Enumerable.Max(myList).

When I said that you could exclude extension methods, I meant that you could make them unavailable to any type, even the .NET types, by not importing the namespace where they are defined. For example, if you did not import the System.Linq namespace to your code file or project, the expression myList.Max() would not compile, and Max would not show up in IntelliSense on an object of type List<T>.

4. Lastly what if you want some of these extension methods for your custom type but not all

You can't selectively include or exclude extension methods that are defined in the same namespace. So for the standard query operators, you will have all or none available in a given code file.

I hope that helps.






Re: Visual C# 2008 (Pre-release) New Extension Methods

Azurewrath

Thanks man for replying.

Now it's more clear to me. However I still wonder this:

1. If extension methods work like this, then there is no way my custo type doesn't have these extension methods but only BCL types have.

So in a new project,

List.Max() will exist

but my custom Vector3 type will not.

From what I have understood from your reply, it's all or none, even when you are using them in a new project.

2. Lastly this also ties a little bit to my question #1 here. It looks like you can't remove some of the extension methods, but wouldn't it be senseless to have an extension method like:

CollectionOfNumbers.Average()

appear for a string collection too

How can you average a string




Thanks,
Aw




Re: Visual C# 2008 (Pre-release) New Extension Methods

Genevieve Orchard - MSFT

In answer to your questions:

1. Extension methods are type specific. The type that they extend is determined by the first parameter in the declaration of the extension method. LINQ's standard query operators extend type IEnumerable<T>. For example, one of the Enumerable.Max() overloads is defined as "public static int Max(this IEnumerable<int> source)". The "this" keyword marks the method as an extension method. The fact that the first parameter is of type IEnumerable<int> means that this extension method can be applied to any object of type IEnumerable<int> or of a type that implements IEnumerable<int>. There are similar overloads of Max for the other numeric types, as well as overloads for IEnumerable<T> where T can be any type. So if your type Vector3 implements IEnumerable<T>, then the standard query operator extension methods will be available on Vector3 objects.

2.
A string is an IEnumerable<char> which is why the IEnumerable<> extension methods can be applied to a string. Because 'char' is non-numeric but an average is a numeric value, to use the Average() extension method on a string you will need to use an overload that takes a function that converts a char into a numeric value. For example:

s.Average(c => c.GetHashCode())

Does that help






Re: Visual C# 2008 (Pre-release) New Extension Methods

Azurewrath

Thanks again for replying.

Actually I haven't used Average but I used Max on a List of strings, and it actually returned an item. But how does it do that I mean extension methods are great, but how will Max/Min/Average, etc will work on my Vector3 class when those things don't exist for vectors in reality

But it could be that I don't know IEnumerable much. So I know I can make a list/array of my Vector3, but does it mean it implements IEnumerable If IEnumerable is able to iterate through a single instance of the class like Vector3.x, Vector3.y, Vector3.z, etc then I see what you mean.




Thanks,
Aw




Re: Visual C# 2008 (Pre-release) New Extension Methods

Genevieve Orchard - MSFT

>>Actually I haven't used Average but I used Max on a List of strings, and it actually returned an item. But how does it do that

The string type implements IComparable<string>, which allows strings to be sorted, etc. That is what the Max() method used to determine which string to return to you.

>>I mean extension methods are great, but how will Max/Min/Average, etc will work on my Vector3 class when those things don't exist for vectors in reality

If your Vector3 class implements IComparable<T>, then Min and Max will make sense. Average will make sense if you can extract a numeric value from your Vector3 objects (like the example in my previous reply). That being said, just because the standard query operators are available for you to use, it doesn't mean that they will always make sense to use on a given type.

>>So I know I can make a list/array of my Vector3, but does it mean it implements IEnumerable

List<T> and Array both implement IEnumerable<T>, so you can use the standard query operators on a list or array of Vector3 objects. If Vector3 itself implements IEnumerable<T>, then you can use the standard query operators on an instance of Vector3. However, it probably does not make sense to "enumerate" a vector, so in all likelihood Vector3 would not implement IEnumerable<T>.






Re: Visual C# 2008 (Pre-release) New Extension Methods

Azurewrath

Thanks alot again!




Aw