简体   繁体   中英

Call overloaded generic method from generic method

My question is: Why is AddData(string data) never called? When I call ds.Add("Some text") then the type of data parameter is known at compilation time thus the overloaded implementation of Add should call AddData(string) method (or this is what I was hoped for)

The output is

Ignore data of type System.String
Ignore data of type System.Double
using System;

namespace GenericCall
{
    interface IDataStore
    {
        void Add<T>(T data);
    }

    class MyDataStore : IDataStore
    {
        public void Add<T>(T data)
        {
            AddData(data);
        }

        private void AddData<T>(T data)
        {
            Console.WriteLine($"Ignore data of type {data.GetType()}");
        }

        private void AddData(string data)
        {
            Console.WriteLine("Accept string data");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyDataStore ds = new MyDataStore();
            ds.Add("Some text");
            ds.Add(3.14);
        }
    }
}

Overload resolution happens at compile time for your code.

At compile time, the compiler has no knowledge of what T actually is, so this call:

public void Add<T>(T data)
{
    AddData(data); <------
}

can only be resolved to the generic AddData , according to the rules of overload resolution .

One way to make overload resolution happen at runtime is to make the public Add accept a dynamic parameter:

// you should change the interface declaration also!
public void Add(dynamic data)
{
    AddData(data);
}

This will produce the output:

Accept string data
Ignore data of type System.Double

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM