I see that there is a similar question for C++. Does anyone know why this method works when the method is non-generic, but as soon as I make it generic, the random number portion of code fails? Error: Cannot implicitly convert type int to 'T'. If I can't use generics, I will have to rewrite the same function over and over for each different length of array.
public void fillGenericArray<T>(T[] inputArray) where T : IComparable
{
var randomNumb1 = new Random();
for (int i = 0; i < inputArray.Length - 1; i++)
{
Console.WriteLine($"{inputArray[i] = randomNumb1.Next(1, 501)},");
}
}
I had to look twice at this, but here's the issue:
Because inputArray is an 'array of type T'
then even though i is an int the expression
inputArray[i]
returns a type T not a type int.
And so, conversely, a type T must be assigned to it.
A generic method like this might achieve your goal:
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
// Where T has a CTor that takes an int as an argument
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
(Thanks to this SO post for refreshing my memory about instantiating T with arguments.)
You could also use Enumerable.Range() to get the same result without writing a method at all:
// Generically, for any 'SomeClass' with a CTor(int value)
SomeClass[] arrayOfT =
Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501)))
.ToArray();
(Slightly Modified with help from this SO post ) - see the answer using Enumerable.Range().
Here is a test runner:
class Program
{
static Random Random { get; } = new Random();
const int LENGTH = 10;
static void Main(string[] args)
{
Console.WriteLine();
Console.WriteLine("With a generic you could do this...");
SomeClass[] arrayOfT;
arrayOfT = new SomeClass[LENGTH];
fillGenericArray<SomeClass>(arrayOfT);
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field=>field.Value)));
Console.WriteLine();
Console.WriteLine("But perhaps it's redundant, because Enumerable is already Generic!");
arrayOfT = Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501))).ToArray();
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field => field.Value)));
// Pause
Console.WriteLine(Environment.NewLine + "Any key to exit");
Console.ReadKey();
}
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
class SomeClass
{
public SomeClass(int value)
{
Value = value;
}
public int Value { get; set; }
}
}
Clone or Download this example from GitHub.
There is no reason to use generics. Just replace T
with int
and you will have function that does what you want (based on your question and comment below it).
EDIT: From your comment it seems you misunderstand the purpose of generics. The non-generic function WILL work for all lengths of the array.
And to answer why the change to generics fails. You are trying to assign int
to generic type T
which can be anything and compiler will not allow such a cast.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.