Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# late binding method overloads does not work when overload is defined in a derived class

I need to call method overloads according to the type of object at runtime using c# late binding features. It works fine when all overloads are defined in the same class as the call is happening. But when an overload is defined in a derived class, it won't get bound at runtime.

class BaseT
{}

class DerivedA : BaseT
{}

class DerivedB : BaseT
{}

class Generator
{
    public void Generate(IEnumerable<BaseT> objects)
    {
        string str = "";
        foreach (dynamic item in objects)
        {
            str = str + this.Generate(item); //throws an exception on second item
        }
    }

    protected virtual string Generate(DerivedA a)
    {
        return " A ";
    }        
}

class DerivedGenertor : Generator
{
    protected virtual string Generate(DerivedB b)
    {
        return " B ";
    }
}



class Program
{
    static void Main(string[] args)
    {
        List<BaseT> items = new List<BaseT>() {new DerivedA(), new DerivedB()};
        var generator = new DerivedGenertor();
        generator.Generate(items);
    }
}

Here is another more clear example:

class BaseT
{}

class DerivedA : BaseT
{}

class DerivedB : BaseT
{}

class DerivedC : BaseT
{ }

class Generator
{
    public void Generate(IEnumerable<BaseT> objects)
    {
        string str = "";
        foreach (dynamic item in objects)
        {
            str = str + this.Generate(item); //throws an exception on third item
        }
    }

    public virtual string Generate(DerivedA a)
    {
        return " A ";
    }

    public virtual string Generate(DerivedC c)
    {
        return " C ";
    }
}

class DerivedGenertor : Generator
{
    public virtual string Generate(DerivedB b)
    {
        return " B ";
    }
}



class Program
{
    static void Main(string[] args)
    {
        List<BaseT> items = new List<BaseT>() {new DerivedA(), new DerivedC(), new DerivedB()};
        dynamic generator = new DerivedGenertor();
        generator.Generate(items);
    }
}
like image 940
Siamak S. Avatar asked Sep 08 '15 22:09

Siamak S.


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C full form?

Full form of C is “COMPILE”.

Why is C named so?

Because a and b and c , so it's name is C. C came out of Ken Thompson's Unix project at AT&T. He originally wrote Unix in assembly language. He wrote a language in assembly called B that ran on Unix, and was a subset of an existing language called BCPL.


1 Answers

You would need to declare the Generator as dynamic as well so that you have dynamic resolution on the input object and on the method being called. But you will have to change the access modifiers to public or protected internal to do this, because you now have an externally resolved method.

class BaseT
{ }

class DerivedA : BaseT
{ }

class DerivedB : BaseT
{ }

class Generator
{
    public string Generate(IEnumerable<BaseT> objects)
    {
        string str = "";
        dynamic generator = this;
        foreach (dynamic item in objects)
        {
            str = str + generator.Generate(item); 
        }
        return str;
    }

    protected internal virtual string Generate(DerivedA a)
    {
        return " A ";
    }
}

class DerivedGenertor : Generator
{
    protected internal virtual string Generate(DerivedB b)
    {
        return " B ";
    }
}



class Program
{
    static void Main(string[] args)
    {
        List<BaseT> items = new List<BaseT>() { new DerivedA(), new DerivedB() };
        var generator = new DerivedGenertor();
        string ret = generator.Generate(items);
    }
}
like image 181
Brian Rudolph Avatar answered Sep 29 '22 23:09

Brian Rudolph