簡體   English   中英

C# 類型 arguments 無法推斷

[英]C# type arguments cannot be inferred

了解 generics.. 我有一個通用數組處理程序,它允許對特定類型進行各種數組操作。 有人告訴我使用IComparable<T>對 T 的約束對測試數據進行排序,但無法弄清楚將條件放在哪里,所以我只使用了使用IComparable<T>Sort<T> T> (即使它得到結果這可能不是我應該如何做到的)。

無論如何,我還有一種方法可以提取數組的一部分,這就是錯誤出現的地方。 比如這個:

CS0411:無法從用法中推斷方法“ArrayHelper_T.GetSubArray(T[], int, int)”的類型 arguments。 嘗試明確指定類型 arguments。

如果我使用我注釋掉的另一個(程序/主程序),我會得到一個不同的錯誤,我也不知道如何修復。 我閱讀了 generics 和接口上的 msdn,並在此處查看了類似的錯誤問題,但這並沒有幫助我找到解決方案。

class Program
{
    static void Main(string[] args)
    {
        ArrayHelper_T<string> strings = new ArrayHelper_T<string>(size: 5);
        strings[0] = "cc";
        strings[1] = "bb";
        strings[2] = "aa";
        strings[3] = "ee";
        strings[4] = "dd";

        strings.SortPrintArray();

        int sub_start_index = 1;
        int sub_length = 3;
            
        ArrayHelper_T<string> sub_strings = new ArrayHelper_T<string>(sub_length);
        
        sub_strings = strings.GetSubArray(array: strings, index: sub_start_index, size: sub_length);
            
        //sub_strings = strings.GetSubArray<ArrayHelper_T<string>>
        //      (array: strings, index: sub_start_index, size: sub_length);
            
        sub_strings.SortPrintArray();
    }
}
public class ArrayHelper_T<T>
    // where T : IComparable<T>
    // , IEnumerable<T>
{
    private T[] array;

    public ArrayHelper_T(int size)
    {
        array = new T[size];
    }

    public T this[int index]
    {
        get { return array[index]; }
        set { array[index] = value; }
    }
    
    public int Size
    {
        get { return array.Length; }
    }
    
    public void SortPrintArray() // where T : IComparable<T>
    {
        if(array.Length > 1)
        {
            Array.Sort<T>(array);
            Console.WriteLine($"Sorted sub-vector: {string.Join("  ", array)} .\n");
        }
        else
        Console.WriteLine($"There is only one element: {array[0]} .\n");
    }

    public T[] GetSubArray<T>(T[] array, int index, int size)
    {
        if( ! (array is null) && (index >= 0 && index < array.Length) &&
            (size <= (array.Length - index + 1)) )
        {
            T[] t = new T[size];
                
            Array.Copy(array, index, t, 0, size);
            return t;
        }

        return Array.Empty<T>();
    }
}

我還有一個次要問題:如何使值初始化不那么塊狀,在一行中,例如strings = {"cc", "bb", "aa", "ee", "dd"}; ?

您正在為 class 和方法使用泛型類型參數,並且將它們混合在一起。

正確的類型聲明將是

public class ArrayHelper_T<T> : IReadOnlyList<T>
    where T : IComparable<T>
{
    private IReadOnlyList<T> array;

    ...

    public void SortPrintArray()
    {
        ...
    }

    public T[] GetSubArray( int index, int size)
    {
        ...
    }
}

另一個非常適合這個例子的替代方法是使用擴展方法。 這跳過了將數組包裝在 class 中的需要,同時仍然允許您像調用實例方法一樣調用方法。

public static class ArrayHelper
{
    public static void SortPrintArray<T>(this T[] array) where T : IComparable<T>
    {
        ...
    }

    public static T[] GetSubArray<T>(this T[] array, int index, int size)
    {
        ...
    }
}

您可能還想實現采用 IComparer object 的重載。 這很有用,因為它允許調用者指定應該如何比較對象。 例如,通過比較 object 的某些屬性而不是對象本身。

public class KeyComparer<T, TKey> : IComparer<T> where TKey : IComparable<TKey>
{
    private readonly Func<T, TKey> selector;
    public KeyComparer(Func<T, TKey> selector) => this.selector = selector;
    public int Compare(T x, T y) => selector(x).CompareTo(selector(y));
}
 public static void SortPrintArray<T, TKey>(this T[] array, Func<T, TKey> selector) where TKey : IComparable<TKey>
        => SortPrintArray(array, new KeyComparer<T, TKey>(selector));
 public static void SortPrintArray<T>(this T[] array, IComparer<T> comparer) 
 {
        //...
  }

暫無
暫無

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

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