-1

I created a specialization for a generic like code below:

public class BaseGeneric<T>
{
    public static T DoStuff()
        => default;
}

public class SpecializedFromBaseGeneric : BaseGeneric<int>
{
    public static new int DoStuff()
        => 789;
}

Now to call the DoStuff() method I would like to use var result = BaseGeneric<int>.DoStuff();

When I run this code, result is 0 instead of 789. The debugger shows that the call will enter the DoStuff() from public class BaseGeneric<T> instead of SpecializedFromBaseGeneric.

What am I doing wrong?

Later edit

I also tried to create specialization in the below format but that does not even compile:

public class BaseGeneric<T> where T : int
{
    public static T DoStuff()
        => 789;
}

I want to do several specializations and use the call similar to the one specified above for int data type BaseGeneric<int>.DoStuff(). And for each specialization use the same syntax where only data type is changed but different implementation is used (eg: for string that would be BaseGeneric<string>.DoStuff()). How to achieve this behaviour?

codiac
  • 1,857
  • 4
  • 18
  • 31
  • 4
    Well you wrote `BaseGeneric.DoStuff()`, so *that* method is called. If you want the method in `SpecializedFromBaseGeneric`, write `SpecializedFromBaseGeneric.DoStuff()`. – Sweeper Jul 08 '22 at 11:10
  • @Sweeper that makes sense but actually I want to do several specializations and use the call similar to this int one `BaseGeneric.DoStuff();` for each specialization (eg: `BaseGeneric.DoStuff();`) – codiac Jul 08 '22 at 11:14
  • C# generics are not C++ templates. There's no specialization. You write one piece of code only that has to work with all types which meet any type constraints for their type parameter. – Damien_The_Unbeliever Jul 08 '22 at 12:36
  • (Bearing in mind that C# generics are actually compiled into the assembly and may be consumed later using types that didn't exist when the generic was authored, leads to different design decisions) – Damien_The_Unbeliever Jul 08 '22 at 12:42
  • This is actually a sign of a code smell. And a XY-problem. You are asking us to fix your solution to a certain problem, but your solution is not a good solution. So the **_real_** question is: why do you want this? What are your trying to do? Give context. – JHBonarius Jul 08 '22 at 14:12
  • Does this answer your question? [Can a static method be overridden in C#?](https://stackoverflow.com/questions/14828271/can-a-static-method-be-overridden-in-c) – Charlieface Jul 08 '22 at 14:12
  • You can't override a static method, you probably need to convert these functions into instance methods – Charlieface Jul 08 '22 at 14:13
  • @Charlieface there's a bigger problem: he/she wants a virtual method with different return type per overload. Without boxing not possible. But like I say: this is just a sign of the wrong tool for the job. – JHBonarius Jul 08 '22 at 14:16
  • @JHBonarius Not quite true: in `SpecializedFromBaseGeneric : BaseGeneric` an instance method would actually return an `int`, no boxing needed. – Charlieface Jul 08 '22 at 14:17
  • @Charlieface but you cannot get an `int` when called from the base. The OP probably wants to use overloading. – JHBonarius Jul 08 '22 at 15:22

2 Answers2

1
    public class BaseGeneric<T> where T : IConvertible
    {
        public static T DoStuff()
        {
            if (typeof(T) == typeof(int))
            {
                return (T)(object)789;
            }

            if (typeof(T) == typeof(string))
            {
                return (T)(object)"ss";
            }

            return default(T);
        }
    }

However, as the asnwer here suggests, this is brittle, and doesn't cover every possible usage.

RandomSlav
  • 507
  • 3
  • 13
  • You are [boxing](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing) this way, thus it's not such a good solution. – JHBonarius Jul 08 '22 at 14:13
0
var result = BaseGeneric<int>.DoStuff()

This one calls the function of a base class. It returns new T(), that equals new int(), that equals zero.

var result = SpecializedFromBaseGeneric.DoStuff()

This one will return what you need.

Hirasawa Yui
  • 1,138
  • 11
  • 29
  • I see. But that is not what I want to achieve. I want to make a specialization. I have updated my question a bit. Thanks. – codiac Jul 08 '22 at 11:12