2

I want to write a method where i can send any type of [], List<>...etc. But in the code when I use T and I want to index the input array, list or anything the error says "Cannot apply indexing with [] to an expression of type 'T'". Theres any solution for this or I have to write a separate code for array, list..etc?

public void NormSort<T>(ref T input, int n)
{
    for (int i = 0; i < n - 2; i++)
    {
        for (int j = 0; j < n - 1; j++)
        {
            if (Comparer<T>.Default.Compare(input[i], input[j]) > 0)
            {
                Swap<T>(input[i], input[j]);
            }
        }
    }
}

public void Swap<T>(T item1, T item2)
 {
     var temp = item1;
     item1 = item2;
     item2 = temp;
 }

So wheres the input[i], input[j], there i got that error.

1
  • For reference, it looks like you're used to using C/C++ pointers (this code reeks of being lifted from pointer-based code); what you're trying to do here maps very well to the upcoming Span<T> mechanism; you should be able to create a Span<T> over most arrays and contiguous lists, and it allows in-place ref access to the data. That isn't an option today, though. Commented Nov 14, 2017 at 11:54

2 Answers 2

4

The easiest way to do that is probably to make the parameter IList<T> for some T, since IList<T> has the indexer support and both arrays and lists implement IList<T>. Note that you probably don't need to pass the n here, since IList<T> also has a .Count property. So:

public void NormSort<T>(IList<T> input) {
    int n = input.Count;
    // ...
}

Note that your Swap method won't work, however; that isn't pass-by-ref, and even if it was: you can't pass indexer values by ref - you need to get and set separately; perhaps:

public static void NormSort<T>(IList<T> input)
{
    int n = input.Count;
    var comparer = Comparer<T>.Default;
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = i; j < n; j++)
        {
            T x = input[i], y = input[j];
            if (comparer.Compare(x, y) > 0)
            {
                input[i] = y;
                input[j] = x;
            }
        }
    }
}

Note that a more typical implementation here would be an extension method:

public static void Sort<T>(this IList<T> input) {...}

Then you can just use:

myListOrArray.Sort();

and as a nice side-effect, if the compiler knows it is a List<T>, it will prefer the inbuilt List<T>.Sort() which will be more efficient - but it will compile for any IList<T> type.

Sign up to request clarification or add additional context in comments.

9 Comments

I should of course note that it is not necessarily a good idea to be writing your own sorting algorithms. List<T>.Sort, Array.Sort, etc, are much better options.
Ohh...So with that i can pass through the whole int[] like this -> List<int[]> asd = new List<int[]>(); But how to pass through a list?
@SzabolcsMészáros var list = new List<int> { 3, 4, 1, 5, 2 }; NormSort(list); System.Console.WriteLine(string.Join(",", list)); - note I don't think the algo works right now, but that's an implementation detail
Note, it was just an example for my problem and its my school task.
@SzabolcsMészáros you wouldn't normally use a list of arrays - that is "jagged". You almost certainly mean List<int> in this case; arrays aren't comparable, for example (you can't ask whether one array is > another array).
|
-2

Use IEnumerable and you can have all type of collections:

public void NormSort<T>(ref IEnumerable<T> input, int n)
{ ...
}

4 Comments

that won't allow indexer usage
True, but you then have ElementAt(N) or ToArray() and then use the indexer.
If you use ToArray you will be modifying a different enumerable so the sorting won't work.
@Stefano that is horribly inefficient, and breaks the intent that you shouldn't rely on enumerables being repeatable, plus enumerables don't have a mechanism to change the values, plus if you manage to it breaks the enumerable; ToArray creates a copy of the data, so doesn't help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.