⬆️ ⬇️

In generic C #, this type could be useful.

Analyzing our code, I found a place that would obviously require some cleanup. But in order to clean it, the language would need another feature, which I want to discuss. I raised this question also on StackOverflow . It was supported by reputable comrade.



Take two classes, one inheriting from the other. The base class is a generic, in which there is a method that, in a derived closed type, must return an instance of this closed type itself.



For example, like this (note the ??? in the text):



public class Adapter<T>

{

public virtual ??? DoSomething()

{

...

}

}



public class AdaptedString : Adapter< String >

{

public override AdaptedString DoSomething()

{

...

}

}




* This source code was highlighted with Source Code Highlighter .


')

This can not be done, since there is no way to refer to the type obtained by “closing” the generic. There is no such keyword that can be replaced with “???” to indicate that this method will return an instance of the derived closed class.



Instead, there is only a workaround. You must explicitly pass the type to the base class. It turns out clearly redundant:



public class Adapter<TThis,T>

{

public virtual TThis DoSomething()

{

...

}

}



public class AdaptedString : Adapter< AdaptedString , String >

{

public override AdaptedString DoSomething()

{

...

}

}




* This source code was highlighted with Source Code Highlighter .




And if in the base class you need to refer to the methods of the instance of type TThis, then you have to add the constraint. And it turns out quite scary:



public class Adapter<TThis,T>

where TThis : Adapter<TThis, T>

{

protected int _field;

...

public bool Compare( TThis obj )

{

return _field == obj._field;

}

}



public class AdaptedString : Adapter< AdaptedString , String >

{

...

}




* This source code was highlighted with Source Code Highlighter .




Basically, it works. But it looks very incomprehensible. Every time you look at this code, you get confused, and you need some time to figure out who is who.



It would seem much more convenient if you could somehow indicate that “TThis” should be this type . Maybe use some keyword. Type “thistype”, although it also looks scary. It may be the constraint to enter:

where TThis: this type



But it turns out that this district path allows you to easily nakosyachit:



class TypeA : Adapter<TypeA, string >



class TypeB : Adapter<TypeA, string > // Bug!




* This source code was highlighted with Source Code Highlighter .

Source: https://habr.com/ru/post/69813/



All Articles