tags:

views:

188

answers:

5

Is it possible to override an internal method's behavior?

using System;

class TestClass
{
    public string Name { get { return this.ProtectedMethod(); } }

    protected string ProtectedMethod()
    {
        return InternalMethod();
    }

    string InternalMethod()
    {
        return "TestClass::InternalMethod()";
    }
}

class OverrideClassProgram : TestClass
{   // try to override the internal method ? (doesn't work)        
    string InternalMethod()
    {
        return "OverrideClassProgram::InternalMethod()";
    }

    static int Main(string[] args)
    {
        // TestClass::InternalMethod()
        Console.WriteLine(new TestClass().Name);
        // TestClass::InternalMethod() ?? are we just screwed?
        Console.WriteLine(new OverrideClassProgram().Name); 
        return (int)Console.ReadKey().Key;
    }
}
A: 

Try using the override keyword ... the new keyword is to call a class constuctor

Sdry
You can't make private/internal methods abstract/virtual so it generates an error.
Jeff Dahmer
You can make `internal` methods `virtual`.
SLaks
The new keyword is not just for instantiating a new object. You can use it to reimplement (a form of overriding) a method. http://www.akadia.com/services/dotnet_polymorphism.html
xanadont
Oh, thanks for the link, learning along the way.
Sdry
@xanadont: hiding, which is what the "new" keyword does in that context, definitely is not overriding. It's an alternative to overriding, maybe could be considered a form of overloading, but definitely not a form of overriding.
Ben Voigt
@Ben I was using "override" in the general sense of the term since the original poster was; he wasn't using the term in the specific sense that C# does.
xanadont
+3  A: 

I think you've got something confused here. There is an actual keyword "internal", is this what you want?

internal string InternalMethod()
{
    return "TestClass::InternalMethod()";
}

But I think what you're really looking for is the "virtual" keyword. This allows you to do an override: Parent Class

protected virtual string InternalMethod()
{
    return "TestClass::InternalMethod()";
}

Child Class

protected override string InternalMethod()
{
    return "TestProgram::InternalMethod()";
}

Using the "new" keyword is valid, but it completely reimplements the method. I.e. it breaks polymorphism.

Edit: Here's a link.

xanadont
A: 

Sure, it's possible, but in order to override a method, the method needs to be virtual or abstract, same as any other visibility.

class Base
{
    internal virtual void Foo()
    {
        Console.WriteLine("Foo from Base");
    }
}

class Derived : Base
{
    internal override void Foo()
    {
        Console.WriteLine("Foo from Derived");
    }
}

When you use the new keyword, it's called method hiding, which is not the same thing. If I write this:

class Base
{
    internal void Foo()
    {
        Console.WriteLine("Foo from Base");
    }
}

class Derived : Base
{
    internal new void Foo()
    {
        Console.WriteLine("Foo from Derived");
    }
}

static void Main()
{
    Base b = new Derived();
    b.Foo();
}

Then it will execute the Base Foo method, not Derived. In other words it will print Foo from Base. In the first case, it would still have executed the Derived method and printed Foo from Derived.

Aaronaught
A: 

This may not answer your question, but just to add a cent.

Internal denotes that types or members are accessible only within files in the same assembly. They are public to the assembly but having access slightly less than the public in actual.

MSDN Access Modifiers,

A common use of internal access is in component-based development because it enables a group of components to cooperate in a private manner without being exposed to the rest of the application code. For example, a framework for building graphical user interfaces could provide Control and Form classes that cooperate using members with internal access. Since these members are internal, they are not exposed to code that is using the framework

KMan
A: 

In Java everything is virtual unless it is static/final. In C# you have to explicitly declare an instance method as virtual and then that method cannot be private. This article explains why.

By default all members of a class are private, so if you do not provide an access modifier (other than private of course) the InternalMethod() method in your example is private and cannot be virtual and thus cannot be overridden.

You must change it's access modifier and mark it as virtual and in the child class you must override it for the code to work the way you want it too.

Asher