Federico Allocati Federico Allocati - 1 year ago 41
C# Question

Equivalent of C++'s typedefs/alias use in template programming

I'm working on a C# project, and found myself trying to reproduce a common pattern in C++, but so far have been unable to. An example of what I'm trying to do (in C++):

enum ProductItemTypes {

class ProductItem : PanelItem {
using item_type_t = ProductItemTypes;

enum PaymentItemTypes {

class PaymentItem : PanelItem {
using item_type_t = PaymentItemTypes;

There are different classes that inherit from
and have their own
Then, classes that use
s, can know the corresponding item type and work generically.

Having some sort of similar ability in C# would help me avoid lots of repeated code, but I don't wan't to pass all the types (
, and some more that I have excluded for simplicity) around all the time.

Answer Source

It's hard to tell exactly what your use case is here because you haven't provided an example of this:

Then, classes that use PanelItems, can know the corresponding item type and work generically.

A class using PanelItems directly wouldn't be able to do this. The only way around that would be if the class was a template class that took the type in directly (which I'm guessing is what you actually mean is happening):

template<class T>
class Foo
    using item_type_t = typename T::item_type_T;

You're not going to be able to do this with C#. While syntactically generics and templates look very similar they are two very different beasts. C++ templates are compiled once for every different concrete type substitution that you make. This is also what allows SFINAE to take place. Basically every time the compiler sees a usage of a template, it substitutes in the type parameters and tries to recompile the class or method.

C#'s generics, on the other hand, are compiled exactly once and are agnostic to the type parameters. This is the reason for the existence of generic constraints in C#: it allows you to give the compiler more knowledge about the kinds of types it's going to deal with. It also means C# has no concept of SFINAE because there's no actual substitution done by the compiler.

My opinion is that your current approach is leaky. Basically the different item_type_t types are implementation details of the derived classes and users of those classes must know what that type is in order to work with the type properly. To me this is breaking encapsulation and C++ just provides a mechanism for you to get around this leakiness by hiding knowledge of the type from the programmer and only requiring the compiler to actually know it.

Without more details about exactly what you're trying to do it's difficult to give any suggestions about alternative approaches. I'm fairly confident that there's an alternative design that'll cleanly deal with your problem, but right now this is a bit of an XY problem.