[IronPython] C# code calling IP subclass weirdness

Ernst, Nathan Nathan.Ernst at citadelgroup.com
Mon Nov 14 15:36:06 CET 2005


I'm not certain if this is the cause of the problem - but have you tried
making "DoSomething" on Helper virtual?  My guess would be that in your
example, you're creating a new, non-virtual method in FooHelper that is
hiding its base class's implementation, analogous to this:

 

using System;

namespace TestLib

{

    public class Helper

    {

        int _id;

        public Helper(int id)

        {

            _id = id;

        }

        public void DoSomething()

        {

            Console.WriteLine("Helper");

        }

    }

 

    public class FooHelper

    {

        public new void DoSomething()

        {

            Console.WriteLine("FooHelper");

        }

    }

 

    public class Master

    {

        protected virtual Helper CreateHelper(int id)

        {

            return new Helper(id);

        }

        public void DoSomething()

        {

            Helper helper = CreateHelper(0);

            helper.DoSomething();

        }

    }

}

 

-Nathan Ernst

 

________________________________

From: users-bounces at lists.ironpython.com
[mailto:users-bounces at lists.ironpython.com] On Behalf Of Michael Shilman
Sent: Monday, November 14, 2005 3:02 AM
To: Discussion of IronPython
Subject: [IronPython] C# code calling IP subclass weirdness

 

A question about subclassing, virtual methods, C#/IP interop, etc in
IronPython-0.9.4.  I have a library of two classes Helper & Master
(greatly simplified from my actual situation, but analagous):

 

using System;

namespace TestLib

{

    public class Helper

    {

        int _id;

        public Helper(int id)

        {

            _id = id;

        }

        public void DoSomething()

        {

            Console.WriteLine("Helper");

        }

    }

 

    public class Master

    {

        protected virtual Helper CreateHelper(int id)

        {

            return new Helper(id);

        }

        public void DoSomething()

        {

            Helper helper = CreateHelper(0);

            helper.DoSomething();

        }

    }

}

 

Master has a factory-style method that creates a helper, and then
invokes a method on it.  I want to insert some throw-away behavior, by
subclassing both Master and Helper, so that FooMaster creates a
FooHelper, and then invokes the FooHelper version of DoSomething.

 

from TestLib import *

 

class FooHelper(Helper):

    def __init__(self, id):

        self._id = id

    def DoSomething(self):

        print "FooHelper"

 

class FooMaster(Master):

    def CreateHelper(self, id):

        return FooHelper(id)

 

# === Main ==================

fooMaster = FooMaster()

fooMaster.DoSomething()

 

I expect this to print out "FooHelper". Instead it prints out "Helper".

 

Note that if I were to define the superclasses Helper/Master in Python
instead of C#, everything works like a charm, and it prints out
"FooHelper":

 

class Helper:

    _id = 0

    def __init__(self, id):

        self._id = id;

    def DoSomething(self):

        print "Helper"

 

class Master:

    def CreateHelper(self, id):

        return Helper(id)

    def DoSomething(self):

        self.CreateHelper(10).DoSomething()

 

This leads me to believe it is impossible for a C# object to call a
Python method that overrides a virtual method.  However, also note that
if I define the Helper class to be abstract in C#, it also works fine
and I see "FooHelper".

 

using System;

using System.Text;

 

namespace TestLib

{

    public abstract class Helper

    {

        int _id;

        public Helper(int id)

        {

            _id = id;

        }

        public abstract void DoSomething();

    }

 

    public class Master

    {

        protected virtual Helper CreateHelper(int id)

        {

            return null;

        }

        public void DoSomething()

        {

            Helper helper = CreateHelper(0);

            helper.DoSomething();

        }

    }

}

 

Furthermore, when I simplify things even further, it also works the way
I'd expect:

 

public class Helper

{

    public Helper(int id) { }

    public virtual void DoSomething() { Console.WriteLine("Helper"); }

}

 

public class Master

{

    public Master(Helper helper) { helper.DoSomething();  }

}

 

class FooHelper(Helper):

    def __init__(self, id): pass

    def DoSomething(self): print "FooHelper"

 

Can anybody tell me what's going on?  Is this a bug in IronPython or am
I doing something wrong?

 

Many thanks,

 

Michael

 

 

------------------------------------------------------------------------
-------------------------
-------------------------

CONFIDENTIALITY AND SECURITY NOTICE

This e-mail contains information that may be confidential and 
proprietary. It is to be read and used solely by the intended
recipient(s). 
Citadel and its affiliates retain all proprietary rights they may have
in the 
information. If you are not an intended recipient, please notify us 
immediately either by reply e-mail or by telephone at 312-395-2100 
and delete this e-mail (including any attachments hereto) immediately 
without reading, disseminating, distributing or copying. We cannot give 
any assurances that this e-mail and any attachments are free of viruses 
and other harmful code. Citadel reserves the right to monitor, intercept
and block all communications involving its computer systems.








-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20051114/d6a23caa/attachment.html>


More information about the Ironpython-users mailing list