2

Abstract use case:

// This works fine, but the second template parameter (T2) is redundant.
var correctSyntax = new T3<T1<T2>, T2>();

// This results in a syntax error, working as intended,
// but this kind of error is only possible because of redundancy (T4 have to match T2).
var incorrectSyntax = new T3<T1<T2>, T4>();

// Ideal syntax, that I could not achieve.
var idealSyntax = new T3<T1<T2>>();

More concrete use case:

Imagine the following, I have a class, that is supposed to take a collection, and store an index of it. The class moves the index forward or backward on demand, and takes care of cases, when the index is out of the bounds. The class has a property, that will return the value at the current index, which is ofcourse of type T.

Imagine, that the collection given to this class is a List, that I want to modify down the line. For this reason, I don't want to use IEnumerable in the class handling the collection, instead I want to store it with the concreate type, and make it public, so I can reach it like:

List<T> list = collectionIndexerInstance.Collection;

In this case, I could not find a better way to write the template constraints then this:

public class SelectedListItem<ListType, ItemType> where ListType: IList<ItemType>
{
   public ListType Collection { get; set; }
   public ItemType CurrentValue => Collection[currentIndex];
   
   private int currentIndex;
   ... 
}

This works fine, but when we declare or initialize the class it is reduntant and longer than ideal:

// This works fine, but the second template parameter is redundant.
var correctSyntax = new Example<List<int>, int>();

// This results in a syntax error, working as intended, 
// but this kind of error is only possible because of redundancy.
var incorrectSyntax = new Example<List<int>, float>();

// Ideal syntax, that I could not achieve.
var idealSyntax = new Example<List<int>>();
  • not aware of a method to infer the type argument of a nested generic "outside": but you can reflect on it: https://www.codeproject.com/Tips/5267157/How-to-Get-a-Collection-Element-Type-Using-Reflect – Cee McSharpface Nov 02 '20 at 09:59
  • 1
    I'm pretty sure there is no (sane) workaround this, I know it's not pretty but is it really that much of a problem? – Ron Nov 02 '20 at 09:59
  • Cee McSharpface - I would only need it to make the collection reachable from the outside type safely, but with precise type, so it should be determined at build time. – Szabolcs Bartha Nov 02 '20 at 10:07
  • Ron - It's not that much of a problem, especially in the concrete use case I have layed out, but I was curious. :) Also kind of excited, that I can maybe ask something that have not been asked on SO before. – Szabolcs Bartha Nov 02 '20 at 10:09
  • 1
    Without `ItemType` how would you specify the `where ListType: IList` constraint and the type of the `CurrentValue` property? – György Kőszeg Nov 02 '20 at 11:41
  • György Kőszeg - Well, that was the question, there could be some magic syntax like ListType.TemplateParameters[0] or ListType.FirstTemplateParameter. I mean I get that this harder to read, than the original implementation, but I think folks at MicroSoft could have designed this feature in a more elegant way, if there would be a reason to implement it. :) – Szabolcs Bartha Nov 02 '20 at 12:11
  • related https://stackoverflow.com/a/41234414/1132334 – Cee McSharpface Nov 02 '20 at 13:19

0 Answers0