As we saw in the previous article, in order to solve this exercise, first of all we must declare a non-nested and non-generic class. Let's also remember that the class must be static. Let's see what happens if we declare an extension method in a non-static class:
Como vimos en el artículo anterior, para resolver este ejercicio, primero que todo debemos declarar una clase no anidada y no genérica. Recordemos además que la clase debe ser estática. Veamos que ocurre si declaramos un método de extensión en una clase no estática:
If we place the mouse over the red underline that appears under the class name, we will see that Visual Studio Code
throws the following error message: An extension method must be defined in a non-generic static class (CS1106). Clicking the link we will get to the Compiler Error CS1106
page: Extension methods must be defined in a non-generic static class. The extension methods must be defined as static methods in a non-generic static class.
Si colocamos el mouse sobre el subrayado rojo que nos aparece debajo del nombre de la clase, veremos que
Visual Studio Code
nos lanza el siguiente mensaje de error: Un método de extensión debe definirse en una clase estática no genérica (CS1106). Siguiendo el enlace llegaremos a la página Compiler ErrorCS1106
: Los métodos de extensión deben definirse en una clase estática no genérica. Los métodos de extensión deben definirse como métodos estáticos en una clase estática no genérica.
Since we must extend the Array
class, we have to indicate it in the first parameter of our extension method, by putting the this
keyword first. This parameter will not be necessary in the call, as long as the call is made from the extended class.
Due to their similarities, I have grouped the methods in groups of two. For the Square()
and Cube()
methods the modus operandi is the same. We must take the array and iterate over it and at each iteration, we must find the square or cube of the corresponding element. We could very well do the following:
Ya que debemos extender la clase
Array
, tenemos indicarlo en el primer parámetro de nuestro método de extensión, antecediéndolo con la palabra reservadathis
. Este parámetro no será necesario en la llamada, siempre y cuando dicha llamada se haga desde la clase extendida.
Para la siguiente explicación, he agrupado los métodos en grupos de a dos, debido a sus similitudes. Para los métodosSquare()
yCube()
el modus operandi es el mismo. Debemos tomar la matriz y recorrerla y, a cada vuelta de bucle, hallarle el cuadrado o el cubo al elemento correspondiente. Pudiéramos perfectamente hacer lo siguiente:
But let's remember that the exercise put a small restriction: the original array must not be changed in any case! Since arrays work by reference, we would be modifying the original array, since both would point to the same memory space. We must assign the result to a new array, as follows:
Pero recordemos que el ejercicio nos ponía una pequeña restricción: la matriz original no debe ser cambiada bajo ninguna circunstancia! Ya que los arrays funcionan por referencia, estaríamos modificando el array original, pues ambos apuntarían al mismo espacio en memoria. Debemos asignar el resultado de las operaciones a un nuevo array, como sigue:
For the Average()
and Sum()
methods we proceed in the same way, we iterate over the array and, in this case, at each iteration we store the sum in a variable. I could have reused code and used the Sum()
method inside the Average()
method, as suggested by user Zooram in his solution, but I didn't realize it at the time.
The difference is that for Average()
we are asked that in case the array is empty, NaN
is returned, since the size of the array in that case would be 0
and the division by 0
is not defined. We do this by accessing the Double.NaN
field. Finally we divide the result of the sum by the size of the array and return it. Remember that in C#
only dividend or divisor must be double
for a decimal division to be performed. If both are type int
and the division is not exact, a loss of information will occur and C#
will remove all decimal digits from the division quotient to maintain type consistency and return a type int
result. In addition, after this it would be converted back to double
automatically, since Average()
return data type is indeed double
and C#
allows the implicit conversion from int
to double
.
Para los métodos
Average()
ySum()
procedemos de la misma manera, recorremos el array y, en este caso, a cada vuelta de bucle vamos almacenando la suma en una variable. Podía haber reutilizado código y haber usado el métodoSum()
dentro del métodoAverage()
, tal y cómo sugería el usuario Zooram en su solución, pero no me di cuenta en el momento.
La diferencia es que paraAverage()
nos piden que en caso de estar vacío el array, se devuelvaNaN
, ya que el tamaño del array en ese caso sería0
y la división por0
no está definida. Hacemos esto accediendo al campoDouble.NaN
. Finalmente dividimos el resultado de la suma entre el tamaño del array y lo devolvemos. Recuerda que enC#
sólo basta con que al menos uno, dividendo o divisor, sea de tipodouble
para que se realice una división decimal. Si ambos son de tipoint
y la división no es exacta, ocurrirá una pérdida de información yC#
por detrás eliminará todas las cifras decimales del cociente de la división para mantener la coherencia de tipos y devolver un resultado también de tipoint
. Igualmente, luego de tener efecto dicha pérdida de información, se convertiría de vuelta adouble
de manera automática, ya que el tipo de dato de retorno deAverage()
es precisamentedouble
yC#
permite la conversión implícita desdeint
haciadouble
.
Finally the Even()
and Odd()
methods. Since we do not know how many odd or even values the array contains, we use a dynamic structure to store those values. We iterate over the array and filter those values making use of a simple condition: that the remainder of the division by 2
is 0
for even and 1
for odd numbers. Then we simply use the ToArray()
method of the generic List<T>
class to convert the list into an array and return it.
Por último los métodos
Even()
yOdd()
. Como no sabemos cuantos valores pares o impares contiene el array, utilizamos una estructura dinámica para almacenar esos valores. Recorremos el array y filtramos los valores haciendo uso de una sencilla condición: que el resto de la división entre2
sea0
para los pares y1
para los impares. Luego simplemente utilizamos el métodoToArray()
de la clase genéricaList<T>
para convertir la lista en un array y devolverlo.
And that's it for this exercise. In the next blog I will be analyzing at several alternative answers to mine and explaining them. I hope you enjoyed this article as much as I enjoyed writing it.
Y eso es todo para este ejercicio. En el siguiente blog estaremos viendo varias respuestas alternativas a la mía y explicándolas. Espero hayan disfrutado este artículo tanto como yo disfruté escribiéndolo.
Links [Enlaces]
Array Helpers | Codewars
https://www.codewars.com/kata/525d50d2037b7acd6e000534
This is my repository: Codewars-kata
https://github.com/Kirito0922/Codewars-kata/blob/4e913b40f656a68be2a5ac894ad17450b3996597/ArrayHelpers.cs
Compiler Error CS1106 - C# | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs1106?f1url=%3FappId%3Droslyn%26k%3Dk
C# Solution for Array Helpers by Zooram | Codewars
https://www.codewars.com/kata/reviews/657989825e40360001993dd0/groups/6588443ad3702a0001ede67d
Arithmetic operators - C# reference | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators
Built-in numeric conversions - C# reference | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions
Double.NaN Field (System) | Microsoft Learn
https://learn.microsoft.com/en-us/dotnet/api/system.double.nan?view=net-8.0
English translation made with DeepL Translate
Traducción al Inglés hecha con Deepl Translate
Congratulations @kirito0922! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)
Your next target is to reach 20 posts.
You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
nice to know!!
Happy to show you something new