Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Πρόβλημα στο να καλω (Invoke) constructor με reflection

Îåêßíçóå áðü ôï ìÝëïò RedG. Τελευταία δημοσίευση από το μέλος darklynx στις 13-07-2009, 10:44. Υπάρχουν 15 απαντήσεις.
Σελίδα 1 από 2 (16 εγγραφές)   1 2 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  09-07-2009, 02:48 52314

    Πρόβλημα στο να καλω (Invoke) constructor με reflection



    Γεια χαρά,

    Προσπαθώ να βρώ τον κατάλληλο τρόπο να καλώ constructor και παρολο που δοκίμασα όλους τους τρόπους μου πετάει ένα Exception
    και δεν μπορώ να καταλάβω γιατί.

    Συγκεκριμένα:
    Η κλάση που κάνει το reflection (ExternalAssemblyReflector)
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;

    namespace ExternalAssemblyReflector
    {
        class Program
        {
           
            #region Helper method
        static void DisplayTypesInAsm(Assembly asm)
        {
              Object obj;
          Console.WriteLine("\n***** Type in Assembly *****");
          Console.WriteLine("->{0}", asm.FullName);
          Type ti = asm.GetType("ContrExample1.Rational");
          Console.WriteLine("Type: {0}", ti);
          try
          {
               // Η Rational class εχει εναν constructor public Rational(int t, int d)
              Type[] argTypes = new Type[] { typeof(Int32), typeof(Int32) };
              ConstructorInfo c = ti.GetConstructor(argTypes);
              //H GetConstructor τον βρίσκει
               obj = Activator.CreateInstance(ti);
              //Kαι εδώ προσπαθώ να καλώσω τον constructor αλλα πετάει Exception
              object[] argVals = new object[] { 3, 5 };
              c.Invoke(obj,argVals);
          }
          catch (Exception e)
          {
              Console.WriteLine("Exception caught.");
              Console.WriteLine("Source: " + e.Source);
              Console.WriteLine("Message: " + e.Message);

          }
      }

    H Main καλέι την DisplayTypesInAsm

    }

    To Exception ειναι:
    Exception caught
    Source: mscorlib
    Message: No parameterless constructor defined for this object

    To e.ToString --> System.MissingMethodException: No parameterless constructor defined for this object...

    Μα αφού του δίνω parameters με το argVals και επιπλέον στην κλάση Rational υπαρχει και constructor public Rational()
    παρόλο που λεει οτι ¨No parameterless constructor defined for this object¨

    Μπορεί καποιος να με διαφωτίσει στο που κάνω λάθος, τι μου ξεφεύγει?
     Επισης εχώ χρησιμοποιήσει και την Invoke(args) αλλα πάλι το ίδιο Exception

    Thanks!

    RedG





















  •  09-07-2009, 09:26 52315 σε απάντηση της 52314

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Για την κλάση Rational έχεις κώδικα; Μπορείς να δεις τον κώδικα με τον Reflector ώστε να βεβαιωθείς ότι υπάρχει ο constructor που θες να χρησιμοποιήσεις;

    Δοκίμασε για testing σκοπούς να πάρεις το collection από τους constructors με την GetConstructors και να κάνεις ένα iteration να δεις τι σου βρίσκει για κάθε ConstructorInfo από το array. 


    Vir prudens non contra ventum mingit
  •  09-07-2009, 11:42 52320 σε απάντηση της 52315

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection



    Ο κώδικας της Rational είναι :

    class Rational
        {
            int numerator;
            int denominator;

            public Rational()
            {
                this.numerator = 1;
                this.denominator = 1;
            }

            public Rational(int numerator, int denominator)
            {
                Contract.Requires(denominator != 0);
               
                this.numerator = numerator;
                this.denominator = denominator;
            }

            public int Denominator
            {
                get
                {
                    //Μην σε απασχολει αυτό ειναι pre condition για το struct
                    Contract.Ensures(Contract.Result<int>() != 0);
                    return this.denominator;
                }
               
            }
    }

    Τελικα όταν ο constructor Rational() ειναι σε σχόλια τοτε μου βγαζει το παραπανω
    Exception.

    Αυτο σημαινει οτι για να κανεις Invoke εναν constructor ΠΡΕΠΕΙ ΩΠΟΣΔΗΠΟΤΕ να υπαρχει
    parameterless constructor στην κλάση?? Μα γιατί?

    Αφου το GetConstructor(Type[] objs)  γυρναει οποιον constructor θες ανεξάρτητα απο το εαν υπαρχει Rational(), όμως για να το καλεσεις δεν ισχύει φαίνεται. Και δεν βρίσκω και τιποτα στο Web που να ανφερεται σε αυτό.

    Help!

    Thanks KelMan for your interest!
  •  09-07-2009, 13:09 52323 σε απάντηση της 52320

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Είσαι σίγουρος ότι είναι class και όχι struct; Το Rational Number Class Library είναι στην ουσία struct. Τα structs δεν έχουν default (parameterless) constructors.
    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  09-07-2009, 13:13 52324 σε απάντηση της 52320

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Το exception εμφανίζεται όταν καλείς την CreateInstance, όχι στην Invoke. Ο λόγος είναι ότι η CreateInstance δημιουργεί ένα νέο αντικείμενο και συνεπώς καλεί και τον constuctor . Καθώς καλείς την CreateInstance χωρίς παραμέτρους, το .NET θα ψάξει να βρει parameterless constructor. Για να πετύχεις αυτό που θέλεις απλά καλείς την ActivateInstance δίνοντας τα arguments, π.χ.

     static void Main(string[] args)
            {
                    Type ti = typeof(Rational);
                    Console.WriteLine("Type: {0}", ti);
                    // Η Rational class εχει εναν constructor public Rational(int t, int d)
                    object[] argVals = new object[] { 3, 5 };
                    var obj = Activator.CreateInstance(ti,argVals);
            }
     

    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-07-2009, 13:17 52325 σε απάντηση της 52323

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Μάρκο, δεν υπάρχει κλάση Rational στο .NET Framework. Προφανώς ο RedG έφτιαξε μία δική του κλάση. Εξάλλου η ερώτηση δεν είναι "γιατί δεν βρίσκω parameterless constructor" αλλά "γιατί μου ζητάει parameterless constructor".


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-07-2009, 15:15 52330 σε απάντηση της 52325

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Χμ... Στον κώδικα που έδωσε ο RedG public είναι και ο default constructor. Δε θα έπρεπε να δουλεύει η CreateInstance; Έτσι, όπως έγραψε για Rational class άναψε λαμπάκι και "θυμήθηκα" το link που έδωσα παραπάνω. Αναρωτήθηκα, λοιπόν, μήπως συμβαίνει κάτι άλλο.
    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  09-07-2009, 15:21 52333 σε απάντηση της 52330

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Αν διαβάσεις καλύτερα όσα έγραψε, λέει ότι το πρόβλημα εμφανιζόταν μόλις έκανε comment τον parameterless constructor. Εξάλλου, μία δοκιμή με τον κώδικα δείχνει αμέσως που βρίσκεται το πρόβλημα.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-07-2009, 15:26 52335 σε απάντηση της 52333

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Ωχ!! Έχεις δίκιο! Και γιατί το έκανε αυτό;;!! Λογικό δε θα ήταν μετά να "φάει" exception;


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  09-07-2009, 15:31 52336 σε απάντηση της 52325

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Here's my 2 cent...
    1. H obj = Activator.CreateInstance(ti); δουλεύει κανονικά καθώς η κλάση Rational έχει default parameterless constructor.
    2. Το πρόβλημα που εντοπίζω εγώ είναι ότι καλείς constructor σε ήδη υπάρχον instance

        obj = Activator.CreateInstance(ti);
        object[] argVals = new object[] { 3, 5 };
        c.Invoke(obj, argVals);

    Αν δεις το documentation της Invoke θα δεις ότι πέρνει ως argument ένα instance (εν προκειμένω το obj) μόνο στη περίπτωση που τη καλείς σε MethodInfo. Οπότε έχεις δύο επιλογές α) κρατάς την Activator.CreateInstance(ti, argVals); όπως είπε και ο Παναγιώτης ή β) την σβήνεις και κρατάς την invoke αλλά δίχως το obj argument δηλαδή:

        ConstructorInfo c = ti.GetConstructor(argTypes);
        object[] argVals = new object[] { 3, 5 };
        obj = c.Invoke(argVals);

    ΗΤΗ.


    MSc Konstantinos Pantos
    MCP Software Engineer
    http://blog.pantos.name
    http://kostas.pantos.name
  •  10-07-2009, 21:44 52386 σε απάντηση της 52336

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Thanks παιδια (σε όλους!),

    Όντως αυτα που είπαν ο Παναγιώτης και ο spantos ισχύουν.

    Δουλεύω με το Reflection γιατι πρέπει να παρω info για τα types που υπαρχουν
    σε ένα assembly(.exe/.dll) για να τα στειλω με Sockets(!!!!!!!) σε ένα Java application που
    είναι ένα automated testing infrastructure!
    Τέλος παντων!!
    Σκέφτομαι να χρησιμοπιήσω την:
    Type..::.InvokeMember Method (String, BindingFlags, Binder, Object, array<Object>[]()[])

    ώστε να χρησημοποιώ μόνο αυτή όταν θα θέλω να execute κάποια method ή constructor
    ενός Type(class,interface). Έλπιζω να μου βγεί με αυτη την μέθοδο!

    Ευχαριστώ πολύ παιδια με ξεκολλήσατε! Ελπίζω να μην χρειαστει (πράγμα απίθανο)
    να με ξελασπώσετε πάλι :)

    Thanks

  •  12-07-2009, 16:49 52410 σε απάντηση της 52386

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection



    Ενω ξέρω ότι για κάθε object υπαρχει default constructor η Activate.CreateInstance(ti) οταν την καλω για την κλάση Rational με την Rational να έχει μόνο έναν δικό μου constructor και αυτός με παραμετρους τοτε πεταει Exception :(! Δεν λαμβάνει υποψιν τον default constructor που ανέφερε ο spantos. Κάνω λάθος?
  •  12-07-2009, 17:56 52411 σε απάντηση της 52410

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Σε παρακαλώ, γράψε κανονικά προτάσεις γιατί δεν μπορεί να καταλάβει κανείς τί γράφεις. Τί πρόβλημα έχεις τώρα? Σε κλάση στην οποία έχεις βάλει και απλό constructor δεν δουλεύει η CreateInstance? Ή σε κλάση χωρίς απλό constructor? Τί εννοείς "ενώ ... για κάθε object υπάρχει default constructor"? Δεν ισχύει κάτι τέτοιο.

    Αν μία κλάση δεν έχει δηλωμένο κανένα constructor, τότε μόνο το Framework θα της δώσει ένα default constructor. Αν έχεις ορίσει εσύ ένα constructor το framework δεν θα προσθέσει τίποτε. Από τη στιγμή που δηλώνεις ένα constructor με παραμέτρους είναι πλέον αδύνατο να δημιουργήσεις ένα αντικείμενο Rational με new Rational(). 

    Αυτή τη στιγμή υποψιάζομαι ότι σε μπερδεύει το Reflection σχετικά με το τί επιτρέπεται και τί όχι. Αντί να δουλεύεις με reflection δοκίμασε απλά να δεις αν μπορείς να κάνεις new την κλάση που θέλεις με τον τρόπο που θέλεις. Αν δεν κάνει compile το απλό new Rational(), αποκλείεται να δουλέψει και η CreateInstance χωρίς παραμέτρους.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  13-07-2009, 02:03 52416 σε απάντηση της 52411

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection



    Οκ sorry γαι τις συντομες προτασεις!

    Πριν εννοούσα οτι εάν η κλάση που θέλω έχει έναν .ctor με παραμετρους που έχω γράψει εγώ, είχα την πεποίθηση ότι o compiler βάζει και έναν default parametereless το οποίο τελικά δεν ισχύει παρα μονο εαν δεν υπάρχει κανενας .ctor. Δυστυχώς πρέπει να χρησιμοποιήσω Reflection γιατι πρεπει να πάρω όλες τις πληροφορίες ενός assembly έχοντας μονο το PE File αυτου του assembly σαν input. Άρα πρέπει το assembly που θα μου δινουν ή να έχει parameterless .ctor declared ή να μην έχει καθόλου για να βάζει το Framework τον default.

    όλα αυτά τα ψάχνω γιατι μονο στον runtime χρόνο θα ξέρω τι πρέπει να κάνω Invoke άρα πρέπει να μπορώ να Instantiate a Type χωρίς άλλη πληροφορία παρα μόνο ποια μέθοδος
    να καλεστεί.

    Παναγιώτη σε ευχαριστώ για την βοηθεια σου. Sorry για το πρίξιμο
  •  13-07-2009, 07:54 52417 σε απάντηση της 52416

    Απ: Πρόβλημα στο να καλω (Invoke) constructor με reflection

    Μήπως τότε σε αυτήν την περίπτωση θα έλυνες το πρόβλημα μέσω Interfaces; Αν υπάρχει προκαθορισμένο Interface που το υλοποιεί το object σου, τότε είσαι σίγουρος ότι υπάρχει το functionality που χρειάζεσαι. Ποιό είναι το γενικότερο σενάριο που προσπαθείς να υλοποιήσεις;


    Vir prudens non contra ventum mingit
Σελίδα 1 από 2 (16 εγγραφές)   1 2 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems