casting problems in c#

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Simon X-Session

    #1

    casting problems in c#

    Hi !

    I hope somebody can help me, i'm completly out of mind.
    My problem:

    I have a class inherited from Windows.Forms.C ontrol named BasicModule,
    which implements an interface named IModule (this has nothing to do
    with the Module-Class of the framework. it's selfmade).

    Now when I instantiate an object dynamically from an assembly created
    from the source of BasicModule, i'm able to cast this object to
    Control, but not to IModule, not even to BasicModule.

    so that you can imagine something:

    public class BasicModule : Control, IModule
    { ... }

    public interface IModule
    { ... }

    now the critical part:

    ModuleEntity selected = (ModuleEntity)t rvQueries.Selec tedNode.Tag;
    object instance = selected.Librar y.CreateInstanc e("DAP." +
    selected.Descri ption.Class,tru e);
    pnlModule.Contr ols.Add((Contro l)instance);
    ((IModule)insta nce).DBConnecti on = dbConnection;

    ModuleEntity holds information about the loaded assembly (stored in
    member "Library", "DAP" is namespace of project)
    pnlModule is a panel to which i want to add the control

    it just doesn't work !
    the debugger even tells me, that "instance" is of type BasicModule,
    but i'm not able to cast it to this class


    i also tried to make a abstract base-class, which inherits Controls
    and implements IModule
    and inherit BasicModule from this base-class
    but i also can't cast to that abstract base-class !

    i'm freaking out

    please help me, i'm in serious trouble if i don't solve the problem
    soon


    ps: it's an requirement, that i can load any assembly-class, which
    implements the IModule interface, at runtime
    this is the base of an extensible application which loads specific
    dlls described in some xml-configuration-file
    so you don't have to rebuild the application when adding new modules
  • Simon X-Session

    #2
    Re: casting problems in c#

    Jon Skeet <skeet@pobox.co m> wrote in message news:<MPG.19af4 766a756350198a3 66@news.microso ft.com>...[color=blue]
    > Simon X-Session <x-session@gmx.at> wrote:
    >
    > <snip>
    >[color=green]
    > > it just doesn't work !
    > > the debugger even tells me, that "instance" is of type BasicModule,
    > > but i'm not able to cast it to this class[/color]
    >
    > This usually happens if you've got the base class/interface present in
    > two different assemblies - the dynamically loaded one and the
    > "driving" one. Put it in just one place, and you should be fine.[/color]

    i don't know if i understand you right
    i need to have the interface in both assemblys, otherwise it wouldn't
    compile

    well, i coded a little sample program to demonstrate my problem:


    (BaseClass.cs)
    namespace CastTest
    {
    public class BaseClass
    {
    private int x;
    public BaseClass()
    {
    x = 0;
    }
    public int X
    {
    set { x = value; }
    get { return x; }
    }
    }
    }

    (ITest.cs)
    namespace CastTest
    {
    public interface ITest
    {
    int Square();
    }
    }

    (TestClass.cs)
    namespace
    {
    public class TestClass : BaseClass, ITest
    {
    public TestClass()
    {
    X = 5;
    }
    public int Square()
    {
    return X*X;
    }
    }
    }


    first: test it with normal object instantiation (CastTest.cs)

    (Test.cs)
    namespace CastTest
    {
    public class MainClass
    {
    public static void Main(string[] args)
    {
    try
    {
    object instance = new CastTest.TestCl ass();
    int x = ((CastTest.ITes t)instance).Squ are();
    // just a test, cast to TestClass
    int y = ((CastTest.Test Class)instance) .Square();
    System.Console. Write("x ok: " + x);
    System.Console. Write("\ny ok: " + y);
    }
    catch (System.Excepti on e)
    {
    System.Console. Write(e.Message );
    }
    }
    }
    }

    compiles and runs fine

    second: test it with loading assembly (Test.cs)

    (Test2.cs)
    namespace CastTest
    {
    public class MainClass
    {
    public static void Main(string[] args)
    {
    try
    {
    System.Reflecti on.Assembly as =
    System.Reflecti on.Assembly.Loa dFrom("CastTest .dll");
    System.Console. Write("Assembly loaded: " +
    as.ToString());
    object instance =
    as.CreateInstan ce("CastTest.Te stClass");
    System.Console. Write("Instance created: " +
    instance.ToStri ng());
    int x = ((CastTest.ITes t)instance).Squ are();
    int y = ((CastTest.Test Class)instance) .Square();
    System.Console. Write(x);
    }
    catch (System.Excepti on e)
    {
    System.Console. Write("\n" + e.Message);
    }
    }
    }
    }

    i compile the base classes to a library
    ..\>csc /target:library /out:CastTest.dl l BaseClass.cs ITest.cs
    TestClass.cs

    and compile main class including other cs-file (otherwise it doesn't
    compile cause he doesn't know ITest)
    ..\>csc Test.cs ITest.cs

    loading of assembly and instatiation of class works flawlessly, but as
    soon as i want to cast the object reference to the interface, it fails
    drop the line where i cast to the interface and uncomment the test to
    cast to "TestClass"
    even this fails in runtime
    notive the output of ToString() of instance
    it says CastTest.TestCl ass !!
    so this class should be save to be casted

    Comment

    • Jon Skeet

      #3
      Re: casting problems in c#

      Simon X-Session <x-session@gmx.at> wrote:[color=blue][color=green]
      > > This usually happens if you've got the base class/interface present in
      > > two different assemblies - the dynamically loaded one and the
      > > "driving" one. Put it in just one place, and you should be fine.[/color]
      >
      > i don't know if i understand you right
      > i need to have the interface in both assemblys, otherwise it wouldn't
      > compile[/color]

      No you don't. You need to add a reference to the assembly which
      contains the interface in order to compile against it.

      You may well decide to put the interface in a separate (and thus very
      small) assembly on its own, and add a reference to that assembly for
      both of the other assemblies.

      <snip>
      [color=blue]
      > loading of assembly and instatiation of class works flawlessly, but as
      > soon as i want to cast the object reference to the interface, it fails
      > drop the line where i cast to the interface and uncomment the test to
      > cast to "TestClass"
      > even this fails in runtime
      > notive the output of ToString() of instance
      > it says CastTest.TestCl ass !!
      > so this class should be save to be casted[/color]

      No it shouldn't - because if you output GetType()==type of(ITest) you'll
      find they're not the same types. Basically you end up with two separate
      types in memory, both for the same type name. The cast is using the
      version loaded in its assembly, but the actual type is the one in the
      assembly containing the test class.

      --
      Jon Skeet - <skeet@pobox.co m>
      Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

      If replying to the group, please do not mail me too

      Comment

      Working...