Dee J. Doena
Dee J. Doena

Reputation: 1843

Generics method signature and standard signature identical

assume you have a class which has methods using T. And you also have standard methods of the same name.

What happens if T is of the same type as the standard method? The standard method is called.

Is there any way to force him to call the T-method anyway?

using System;

namespace ConsoleApplication3
{
class Program
{
    static void Main()
    {
        Generics<Int32> anInt = new Generics<Int32>(4);
        Generics<String> aString = new Generics<String>("test");
    }
}

public class Generics<T>
{
    public T Member;

    public String ErrorMessage;

    public Generics(T member)
    {
        this.Member = member;
    }

    public Generics(String errorMessage)
    {
        this.ErrorMessage = errorMessage;
    }
}
}

Upvotes: 9

Views: 1095

Answers (3)

Dee J. Doena
Dee J. Doena

Reputation: 1843

I simply did this (for this specific case):

I added an empty protected constructor to Generics

    protected Generics() { }

And then I derived for the specific case of T = string

    public class GenericsOfString : Generics<String>
    {
        public GenericsOfString(String text, Boolean isErrorMessage)
        {
            if (isErrorMessage)
            {
                this.ErrorMessage = text;
            }
            else
            {
                this.Member = text;
            }
        }
    }

Upvotes: 0

sq33G
sq33G

Reputation: 3360

Okay, I'll make my comment into an answer.

First of all, DO NOT do this. DO NOT. You want humans to be able to read your code, not just computers. (There, I've done my duty as a member of the C# programmer space)

Second.

As described here:

If you design your code so that the compiler cannot tell when it's compiling what type you're calling with, you can force it to use the generic method.

static Generics<T> Test<T> (T parameterToTest) {
    return new Generics<T>(parameterToTest);
}

static void Main()
{
    Generics<Int32> anInt = Test<Int32>(4);
    Generics<String> aString = Test<String>("test");
}

Upvotes: 1

Christian Hayter
Christian Hayter

Reputation: 31071

Sorry, there is not.

The simplest solution is to use two different method names to indicate the difference in behaviour. Since the method names in question are constructors, you have no control over the names, so you must change at least one of them into a normal method instead. For example:

public class Generics<T>
{
    public T Member;

    public String ErrorMessage;

    public Generics(T member)
    {
        this.Member = member;
    }

    private Generics()
    {
        // empty constructor just to allow the class to create itself internally
    }

    public static Generics<T> FromError(String errorMessage)
    {
        return new Generics<T> { ErrorMessage = errorMessage };
    }
}

Personally I would change both constructors to be static methods, so that the difference in behaviour is made absolutely clear to the user. However, if you only change one constructor, make it the error one.

Upvotes: 5

Related Questions