veda
veda

Reputation: 6614

Can the C# generic methods be overloaded similar to C++ function overloading

Can C3 generic methods be overloaded similar to that of C++ function overloading.

Is the below code right way to overload the generic methods

class ReadFile<T> : IDisposable
{

    private FileStream fstream;
    private BinaryReader br;

    public ReadFile(string filename)
    {
       // do all the initialization
    }

    public void readValue(double val)
    {
       val = br.ReadDouble();
    }

    public void readValue(float val)
    {
       val = br.ReadSingle();
    }

    public void readValue(T val)
    {
       throw new Exception("Not implemented");
    }
}

Upvotes: 0

Views: 168

Answers (2)

Moho
Moho

Reputation: 16553

Instead of templating the class, you need to template the readValue method. You can then use good ol' fashioned overloading to implement explicit types. Don't forget to add the out keyword to your readValue parameters. Quick console app demo:

class Program
{
    static void Main(string[] args)
    {
        var rf = new ReadFile();

        double d;
        float f;
        int i;

        Console.WriteLine(string.Format( "{1}: {0}", rf.readValue(out d), d ));
        Console.WriteLine(string.Format( "{1}: {0}", rf.readValue(out f), f ));
        // note you don't have to explicitly specify the type for T
        // it is inferred
        Console.WriteLine(string.Format( "{1}: {0}", rf.readValue(out i), i ));

        Console.ReadLine();
    }
}

public class ReadFile
{
    // overload for double
    public string readValue(out double val)
    {
        val = 1.23;
        return "double";
    }

    // overload for float
    public string readValue(out float val)
    {
        val = 0.12f;
        return "float";
    }

    // 'catch-all' generic method
    public string readValue<T>(out T val)
    {
        val = default(T);
        return string.Format("Generic method called with type {0}", typeof(T));
    }
}

Upvotes: 3

supercat
supercat

Reputation: 81247

While some people argue against the use of generics for things like you describe, there are times when they are appropriate. Nonetheless, there isn't a particularly convenient pattern for having different code execute for different types. Probably the best approach is to have your private static Action<T> readProc = InitReadProc; and have the generic ReadValue(T val) call readProc(val). The InitReadProc method could look something like:

ReadFile<float>.readProc = readValue; // Binds to `float` overload
ReadFile<double>.readProc = readValue; // Binds to `double` overload
// etc. for all known overloads
if (readProc == InitReadProc) // The readProc of *this* type (T) didn't get set above
  throw new NotSupportedException(String.Format("Type {0} not available", typeof(T));
else
  readProc();

Using this approach, the first time any attempt is made to call the generic readValue for any type, it will fill in the readProc delegates for all known types. Any future attempt to call readValue on any such type will be dispatched via the delegate to the appropriate method. Note that if desired one could offer a ConfigureReadProc<T>(Action<T> proc) method to allow consumers of the class to set up ReadFile methods for other types. One could also if desired use Reflection to check whether type T supported a static readValue(T) method and, if so, attach the delegate to that.

Upvotes: 0

Related Questions