簡體   English   中英

C# 生成隨機數的通用方法

[英]C# Generic method for random number generation

我看到 C++ 也有類似的問題。 有誰知道為什么該方法在非泛型時有效,但是一旦我將其設為泛型,代碼的隨機數部分就會失敗? 錯誤:無法將 int 類型隱式轉換為“T”。 如果我不能使用 generics,我將不得不為每個不同長度的數組一遍又一遍地重寫相同的 function。

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

我不得不看兩次,但這是問題所在:

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

(感謝這篇 SO 帖子刷新了我關於用 arguments 實例化 T 的 memory。)

您也可以使用 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();

(在此 SO 帖子的幫助下稍作修改) - 使用 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; }
    }
}

控制台輸出

從 GitHub克隆或下載此示例。

沒有理由使用 generics。 只需將T替換為int ,您將擁有 function 可以滿足您的需求(根據您的問題和下面的評論)。

編輯:從您的評論看來,您誤解了 generics 的目的。 非通用 function 將適用於數組的所有長度。

並回答為什么更改為 generics 失敗。 您正在嘗試將int分配給可以是任何東西的泛型類型T ,編譯器將不允許這樣的強制轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM