Toon posts:

[C#] Kan geen classes dynamic maken

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo allemaal,
ik heb volgende code:

bot.cs
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Reflection;

public class AI {
    
    public string MakeAI() {
        Assembly asm = Assembly.LoadFrom("ai.dll");
        botAI = (IBotAI) asm.CreateInstance("BotAI");
        return "";

        
    }
    IBotAI botAI = null;
}

public class Bot {
    public static void Main(string[] args) {
        AI a = new AI();
        Console.WriteLine(a.MakeAI());
    }
}


classes.cs
code:
1
2
3
4
public interface IBotAI {
    string MakeAI();
    void test(string a);
}


en ai.cs:
code:
1
2
3
4
5
6
7
8
using System;

public class BotAI : IBotAI {
    public string MakeAI() {
        Console.WriteLine("test");
        return "a";
    }
}


Ik probeer dus in bot.cs de klasse BotAI (van het type IBotAI) dynamisch in te laden en te gebruiken.
Maar ik krijg volgende fout als ik bot.exe start:
code:
1
2
3
Unhandled Exception: System.InvalidCastException: Cannot cast from source type to destination type.
in <0x00053> AI:MakeAI ()
in <0x00026> Bot:Main (System.String[] args)

Dit fout wordt veroorzaakt op de achtste regel van bot.cs. Maar ik vind niet wat er fout is: ik kan dat toch omzetten naar IBotAI ?

Ah nog iets: ik maak gebruik van Mono onder linux en niet van de ms .net framework, zou dit een verschil kunnen maken ?
Alvast bedankt om eens te kijken :)

[ Voor 9% gewijzigd door Verwijderd op 07-07-2005 17:08 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 21:58
Debug je code eens, check eens de documentatie van de CreateInstance method, kijk eens wat CreateInstance in jouw geval returned.
Indien het object niet kan gemaakt worden, dan returned CreateInstance NULL, en ik denk dat dit bij jou het geval is.

Je zult nl. ook de namespace moeten opgeven waarin de class BotAI zich bevind.

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op donderdag 07 juli 2005 @ 17:09:
Debug je code eens, check eens de documentatie van de CreateInstance method, kijk eens wat CreateInstance in jouw geval returned.
Indien het object niet kan gemaakt worden, dan returned CreateInstance NULL, en ik denk dat dit bij jou het geval is.

Je zult nl. ook de namespace moeten opgeven waarin de class BotAI zich bevind.
CreateInstance heeft geen null terug, als ik volgende code uitprobeer:
code:
1
Console.WriteLine(asm.CreateInstance("BotAI").ToString());

Schrijft het "BotAI" in de console, dus er wordt wel degelijk een instance van BotAI gemaakt.
En de class BotAI bevindt zich niet in een namespace.

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:58
Van welk type is botAI in bot.cs op regel 8 ?

Ben je wel zeker dat die BotAI class die interface implementeert ?

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op donderdag 07 juli 2005 @ 17:20:
Van welk type is botAI in bot.cs op regel 8 ?

Ben je wel zeker dat die BotAI class die interface implementeert ?
Van het type "BotAI"

In de code van de klasse BotAI heb ik "public class BotAI : IBotAI" staan, dit betekent toch dat BotAI die interface implementeert

Heb juist volgende code toegevoegd aan ai.cs om de klasse BotAI uit te testen:
code:
1
2
3
4
5
6
public class main {
    public static void Main() {
        IBotAI a = new BotAI();
        a.MakeAI();
    }
}

Dit geeft geen enkel fout terug en doet wat dat het moet doen.

[ Voor 28% gewijzigd door Verwijderd op 07-07-2005 17:27 ]


Verwijderd

Topicstarter
Ik heb het kunnen oplossen maar op een ande manierl
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class AI {
    
    public string MakeAI() {
        Assembly asm = Assembly.LoadFrom("ai.dll");

        theClass = asm.CreateInstance("BotAI");
        theType = asm.GetType("BotAI");

        object[] arguments = new object[1];
        arguments[0] = "aaa";
        theType.InvokeMember("test",
                BindingFlags.Default | BindingFlags.InvokeMethod,
                null,
                theClass,
                arguments);
        arguments = new object[0];
        object retVal = theType.InvokeMember("MakeAI",
                BindingFlags.Default | BindingFlags.InvokeMethod,
                null,
                theClass,
                arguments);
        return (string) retVal;
    }
    object theClass = null;
    Type theType = null;
}


Dit manier ziet er minder mooi uit, maar werkt wel

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:58
Het werkt wel, maar dat is veel minder efficient.

Ik vroeg of je class wel die interface implementeerde, omdat ik in die interface 2 methods zie staan, en jouw class maar 1 method implementeert.

Probeer het nog eens op jouw eerste manier, maar doe het eens met een omweg:

code:
1
2
3
4
5
6
object o = asm.CreateInstance ("BotAI");

IBotAI bot = o as IBotAI;

if( bot == null )
   throw new InvalidOperationException();

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op vrijdag 08 juli 2005 @ 08:45:
Het werkt wel, maar dat is veel minder efficient.

Ik vroeg of je class wel die interface implementeerde, omdat ik in die interface 2 methods zie staan, en jouw class maar 1 method implementeert.

Probeer het nog eens op jouw eerste manier, maar doe het eens met een omweg:

code:
1
2
3
4
5
6
object o = asm.CreateInstance ("BotAI");

IBotAI bot = o as IBotAI;

if( bot == null )
   throw new InvalidOperationException();
De class is wel goed geimplementeerd, maar ik heb een beetje verwijderd voor het hier te plakken.
En dit stuk code heeft een System.InvalidOperationException, dus bot is null.

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:58
Dat wil dan zeggen dat het gereturnde object de IBotAI interface niet implementeert.
Als je in debug-mode eens het object 'o' van dichterbij bekijkt, wat staat daar dan in ?

https://fgheysels.github.io/


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Heb je niet 2 keer IBotAI gedefineerd in beide assemblies? Dan heb je namelijk 2 verschillende interfaces en kan je ze niet casten onderling ook al hebben ze dezelfde definitie

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
whoami schreef op zaterdag 09 juli 2005 @ 20:28:
Dat wil dan zeggen dat het gereturnde object de IBotAI interface niet implementeert.
Als je in debug-mode eens het object 'o' van dichterbij bekijkt, wat staat daar dan in ?
Ik maak gebruik van mono, en die heeft (nog) geen debugger.
Maar ik heb nog een beetje verder getest:
code:
1
2
3
BotAI bot = new BotAI();
IBotAI test = bot as IBotAI;
test.MakeAI();

dit stuk code werkt wel, dus BotAI implementeert wel goed de IBotAI interface.

@ rwb:
Nee, ik heb maar 1x de interface gedefineerd
Pagina: 1