Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling an overloaded method in generic method

Tags:

c#

class Test
{
    public BinaryWriter Content { get; private set; }
    public Test Write<T> (T data)
    {
        Content.Write(data);
        return this;
    }
}

it won't compile.

1. The best overloaded method match for 'System.IO.BinaryWriter.Write(bool)' has some invalid arguments
2. Argument 1: cannot convert from 'T' to 'bool'

it seems like Test.Write is always trying to call BinaryWriter.Write(bool). any suggestions?

like image 723
Laie Avatar asked Mar 15 '14 06:03

Laie


2 Answers

Overload resolution happens at compile-time, and in this case nothing is known about T, so no overload is applicable.

   class Test
    {
        public BinaryWriter Content { get; private set; }
        public Test Write<T>(T data)
        {
            Content.Write((dynamic)data);
            return this;
        }
    }

But of course it could make some problems. For example, appliction will compile fine, if you will send DateTime to the method. But, it will throw exception.

like image 182
Farhad Jabiyev Avatar answered Sep 20 '22 20:09

Farhad Jabiyev


This is possible but not with generic constraints . You can try to use Reflection and get the appropriate overloaded version of Write method according to type of T.

Initialize your BinaryWriter with a Stream in your constructor then use Reflection like below:

class Test
{
    public BinaryWriter Content { get; private set; }

    public Test(Stream stream)
    {
        Content = new BinaryWriter(stream);
    }

    public Test Write<T>(T data)
    {

        var method = typeof (BinaryWriter).GetMethod("Write", new[] {data.GetType()});
        if (method != null)
        {
            method.Invoke(Content, new object[] { data });
        }
        // here you might want to throw an exception if method is not found

        return this;
    }
}

Here is a test program:

Test writer;
using (var fs = new FileStream("sample.txt", FileMode.Open))
{
     writer = new Test(fs);
     writer = writer.Write(232323);
     writer = writer.Write(true);
     writer = writer.Write(12);
}

using (var fs = File.Open("sample.txt", FileMode.Open))
{
    var reader = new BinaryReader(fs);
    Console.WriteLine(reader.ReadInt32());  // 232323
    Console.WriteLine(reader.ReadBoolean()); // true
    Console.WriteLine(reader.ReadByte());    // 12
}
like image 41
Selman Genç Avatar answered Sep 21 '22 20:09

Selman Genç