vendredi 18 avril 2014

C# - retour tableau générique type - Stack Overflow


If I have a simple Utility function that copies an array to a new array:


public static object[] CopyTo(object[] original, int startIndex, int endIndex)
{
List<object> copied - new List<object>();
for (int i = startIndex; i <= endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}

and I want to then be able to call it like this:


int[] newThing = CopyTo(new int[] { 10, 9, 8, 7, 6 }, 2, 4);

the compiler errors saying cannot convert from int[] to object[]. This is expected since my CopyTo function specifically wants an object array, not an integer array.


How can I change the declaration of CopyTo in order for it to dynamically accept and return an array of any type? I believe Generics is the way (though I'm not too familiar with this) so I tried:


public static T[] CopyTo(T[] original, int startIndex......)

but the compiler won't recognise T as a type.




To make it generic use following code:


public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
List<T> copied = new List<T>();
for (int i = startIndex; i <= endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}

Edit:


Just to mention, you can also do this without creating a List<T> and returning the list as an array. Just create an array (with length equal to the count of wanted elements) and fill it up:


public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
int count = (endIndex - startIndex) + 1;
int index = 0;
T[] copied = new T[count];

for (int i = startIndex; i <= endIndex; i++)
copied[index++] = original[i];

return copied;
}

And you could also create an extension method for it:


public static class Extensions
{
public static T[] CopyTo<T>(this T[] source, int start, int end)
{
int count = (end - start) + 1;
int index = 0;
T[] copied = new T[count];

for (int i = start; i <= end; i++)
copied[index++] = source[i];

return copied;
}
}

Now you can call it like:


var original = new int[] { 10, 9, 8, 7, 6 };
var newThing = original.CopyTo(0, 2);

Or for an array of strings:


var strOrig = "one.two.three.four.five.six.seven".Split('.');
var strNew = strOrig.CopyTo(2, 5);



Try this:


public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
List<T> copied = new List<T>();
for (int i = startIndex; i < endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}



I think you don't need to write your own function, the .NET Framework has already everything built in. Look at this example:


void Main()
{
var target = new int[20];
var srcStart=1; var tgtStart=3; var srcElements=3;
Array.Copy((new int[] { 1,2,3,4,5,6,7,8,9 }), srcStart,
target, tgtStart, srcElements);
Console.WriteLine(string.Join(",", target));
}

It works correctly and returns:



0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0





Note there is also a simpler version, the .CopyTo method. It works as follows:


void Main()
{
var target = new int[20];
(new int[] { 1,2,3,4,5,6,7,8,9 }).CopyTo(target, 3);
Console.WriteLine(string.Join(",", target));
}

And it returns:



0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0



You can use it with other data types too, for example:


    var target = new string[20];
(new string[] { "abc", "def", "ghi" }).CopyTo(target, 3);

works in the same way.



If I have a simple Utility function that copies an array to a new array:


public static object[] CopyTo(object[] original, int startIndex, int endIndex)
{
List<object> copied - new List<object>();
for (int i = startIndex; i <= endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}

and I want to then be able to call it like this:


int[] newThing = CopyTo(new int[] { 10, 9, 8, 7, 6 }, 2, 4);

the compiler errors saying cannot convert from int[] to object[]. This is expected since my CopyTo function specifically wants an object array, not an integer array.


How can I change the declaration of CopyTo in order for it to dynamically accept and return an array of any type? I believe Generics is the way (though I'm not too familiar with this) so I tried:


public static T[] CopyTo(T[] original, int startIndex......)

but the compiler won't recognise T as a type.



To make it generic use following code:


public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
List<T> copied = new List<T>();
for (int i = startIndex; i <= endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}

Edit:


Just to mention, you can also do this without creating a List<T> and returning the list as an array. Just create an array (with length equal to the count of wanted elements) and fill it up:


public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
int count = (endIndex - startIndex) + 1;
int index = 0;
T[] copied = new T[count];

for (int i = startIndex; i <= endIndex; i++)
copied[index++] = original[i];

return copied;
}

And you could also create an extension method for it:


public static class Extensions
{
public static T[] CopyTo<T>(this T[] source, int start, int end)
{
int count = (end - start) + 1;
int index = 0;
T[] copied = new T[count];

for (int i = start; i <= end; i++)
copied[index++] = source[i];

return copied;
}
}

Now you can call it like:


var original = new int[] { 10, 9, 8, 7, 6 };
var newThing = original.CopyTo(0, 2);

Or for an array of strings:


var strOrig = "one.two.three.four.five.six.seven".Split('.');
var strNew = strOrig.CopyTo(2, 5);


Try this:


public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
List<T> copied = new List<T>();
for (int i = startIndex; i < endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}


I think you don't need to write your own function, the .NET Framework has already everything built in. Look at this example:


void Main()
{
var target = new int[20];
var srcStart=1; var tgtStart=3; var srcElements=3;
Array.Copy((new int[] { 1,2,3,4,5,6,7,8,9 }), srcStart,
target, tgtStart, srcElements);
Console.WriteLine(string.Join(",", target));
}

It works correctly and returns:



0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0





Note there is also a simpler version, the .CopyTo method. It works as follows:


void Main()
{
var target = new int[20];
(new int[] { 1,2,3,4,5,6,7,8,9 }).CopyTo(target, 3);
Console.WriteLine(string.Join(",", target));
}

And it returns:



0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0



You can use it with other data types too, for example:


    var target = new string[20];
(new string[] { "abc", "def", "ghi" }).CopyTo(target, 3);

works in the same way.


0 commentaires:

Enregistrer un commentaire