随机数生成的C#通用方法

时间:2020-05-30 14:12:15

标签: c# generics random numbers

我看到C ++也有类似的问题。有谁知道为什么该方法在非泛型方法中起作用,但是一旦我将其设为泛型,代码的随机数部分就会失败? 错误:无法将类型int隐式转换为'T'。如果不能使用泛型,则必须针对数组的每个不同长度一遍又一遍地重写同一函数。

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)},");
    }
}

2 个答案:

答案 0 :(得分:2)

我不得不三思而后行,但这是问题所在:

因为 inputArray 是“类型T的数组”

然后,即使 i int 表达式

inputArray[i] 

返回类型T而不是类型int。

因此,反过来,必须为其分配类型T。

这样的通用方法可以实现您的目标:

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));
    }
}

(感谢this SO post刷新了有关使用参数实例化T的记忆。)

您也可以使用Enumerable.Range()获得相同的结果,而无需编写任何方法:

// Generically, for any 'SomeClass' with a CTor(int value)
SomeClass[] arrayOfT = 
    Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501)))
    .ToArray();

(在this SO post的帮助下进行了修改)-使用Enumerable.Range()查看答案。

这是一名测试跑步者:

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; }
    }
}

Console Output

Clone or Download来自GitHub的示例。

答案 1 :(得分:1)

没有理由使用泛型。只需将T替换为int,您将具有执行所需功能的功能(基于您的问题和其下方的评论)。

编辑:从您的评论看来,您似乎误解了泛型的目的。非泛型函数将对数组的所有长度起作用。

并回答为什么对泛型的更改失败。您正在尝试将int分配给泛型类型T,泛型类型可以是任何类型,并且编译器将不允许这种类型的转换。