Generic extension method for array not compiling

When setting up a request object for a web service, I need to dynamically add elements to some arrays.

I was hoping to simplify it by introducing an extension method:

public static class ArrayExtensions<T> where T : class { public static T[] Extend<T>(T[] originalArray, T addItem) { if (addItem == null) { throw new ArgumentNullException("addItem"); } var arr = new[] { addItem }; if (originalArray == null) { return arr; } return originalArray.Concat(arr).ToArray(); } } 

So this old code:

 if (foo.bazArr == null) { foo.bazArr = new[] { baz }; } else { foo.bazArr = new[] { baz }.Concat(foo.bazArr).ToArray(); // (i know this inserts the new item at the beginning, but that irrelevant, order doesn't matter) } 

can be rewritten as:

 foo.bazArr = foo.bazArr.Extend(baz); // won't compile 

Error: 'System.Array' does not contain a definition for 'Extend' and no extension method 'Extend' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)

While the extension method is called like this:

 foo.bazArr = ArrayExtensions<someService.bazType>.Extend(foo.bazArr, baz); 

compiles great.

Why is this so? Why can't the compiler infer a type by itself if the array is strongly typed?


EDIT is the correct code below:

 public static class ArrayExtensions { public static T[] Extend<T>(this T[] originalArray, T addItem) where T : class { if (addItem == null) { throw new ArgumentNullException("addItem"); } var arr = new[] { addItem }; if (originalArray == null) { return arr; } return originalArray.Concat(arr).ToArray(); // although Concat is not recommended for performance reasons, see the accepted answer } } 

For this popular question, here is another good simple example:

 public static class Extns { // here an unbelievably useful array handling extension for games! public static T AnyOne<T>(this T[] ra) where T:class { int k = ra.Length; int r = Random.Range(0,k); return ra[r]; // (add your own check, alerts, etc, to this example code) } } 

and when using.

 someArrayOfSoundEffects.AnyOne().Play(); someArrayOfAnimations.AnyOne().BlendLeft(); winningDisplay.text = successStringsArray.AnyOne() +", " +playerName; SpawnEnormousRobotAt( possibleSafeLocations.AnyOne() ); 

etc. For any array, it will give you one random element. Used constantly in games for random effects, etc. An array can be of any type.

+4
source share
3 answers

This is missing:

 public static T[] Extend<T>(this T[] originalArray, T addItem) 

Without this is not an extension method.

Additional note: expanding an array one element at a time is expensive. A List<T> would be much preferable. Check if your web service has list listings as an option.

Even with arrays, using Enumerable.Concat is likely to overflow here; I would just measure two arrays, CopyTo new one, and use the CopyTo method of each to write to a place in the new array.

+5
source

use this to define an extension method

 public static T[] Extend<T>(this T[] originalArray, T addItem) 
+2
source

you missed the keyword "this"

+1
source

Source: https://habr.com/ru/post/1412314/


All Articles