Frage

Ich habe eine Klasse, die den folgenden Konstruktor hat

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;  
}

zusammen mit einem Standard-Konstruktor ohne Parameter.

Als nächstes Ich versuche, eine Instanz zu schaffen, aber es funktioniert nur ohne Parameter:

var designer = Activator.CreateInstance(designerAttribute.Designer);

Das funktioniert ganz gut, aber wenn ich will Parameter übergibt es nicht:

var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));

Dies führt zu einer MissingMethodException:

  

Constructor voor Typ   Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesigner   wurde nicht gefunden

Irgendwelche Ideen hier?


Das Problem ist, ich muß wirklich ein Objekt während der Bauphase weiter.

Sie sehen, ich habe einen Designer, der alle Arten lädt, die von der CompositeBase erben. Diese werden dann zu einer Liste, aus denen die Benutzer, um sie zu einem Designer ziehen. Nach tut, ist der Designer so eine Instanz des gezogenen hinzugefügt. Jede dieser Klassen haben benutzerdefinierte Eigenschaften definiert auf sie:

[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase
{
}

Wenn der Benutzer ein Element im Designer wählt, sieht es bei diesen Attributen, um einen Designer für diesen Typen zu laden. Zum Beispiel im Fall des DelayComposite wäre es lädt ein Benutzersteuer auf, die eine Markierung und einen Schieber, der der Benutzer die „Delay“ Eigenschaft der DelayComposite Instanz festgelegt ermöglichen hat.

Bisher das funktioniert gut, wenn ich an den Konstruktor Parameter übergeben nicht. Der Designer erstellt eine Instanz des DelayCompositeDesigner und weist sie den Inhalt Eigenschaft eines WPF ContentPresenter.

Da aber, dass Designer brauchen, um die Eigenschaften des ausgewählten DelayComposite ändern im Designer, muss ich diese Instanz, um es passieren. Deshalb ist der Konstruktor sieht liegen diese:

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;
}

Vorschläge sind willkommen


@VolkerK

Das Ergebnis des Codes ist dies:

  

<---- foo   Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid   .ctor ()   Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid   .ctor (Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite)   param: Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite   foo ---->


leppie, Sie waren richtig, ich aus irgendeinem Grunde hatte die Composites Montag in meiner UI Anwendung verwiesen ..., die nicht etwas, was ich getan haben sollte, wie ich es zur Laufzeit geladen werden. Der folgende Code funktioniert:

object composite = Activator.CreateInstance(item.CompositType,(byte)205);
                    var designer = Activator.CreateInstance(designerAttribute.Designer, composite);

Wie Sie den Code hat keine Kenntnis von der DelayComposite Art sehen.

Das das aktuelle Problem löst, stellt aber viel neues für das, was ich erreichen will, entweder Weise danke und danke an alle, die hier geantwortet hat.


Wie für den folgenden Code, von mehreren Personen vorgeschlagen:

var designer = Activator.CreateInstance(
    designerAttribute.Designer, 
    new object[] { new DelayComposite(4) } 
);

Die Activator.CreateInstance hat eine Signatur, die wie folgt aussieht:

Activator.CreateInstance(Type type, params object[] obj)

So sollte es meinen Code akzeptieren, aber ich werde den vorgeschlagenen Code versuchen

UPDATE:

Ich habe schon versucht, diese wie vorgeschlagen:

var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4)});

Das Ergebnis ist das gleiche.

War es hilfreich?

Lösung

Ich glaube, Sie mit einem Typenkonflikt handelt.

Wahrscheinlich wird die Anordnung an verschiedenen Stellen verwiesen, oder sie sind gegen verschiedene Versionen zusammengestellt.

Ich schlage vor, Sie die ConstructorInfo die durchlaufen und machen einen paramtype == typeof(DelayComposite) auf den entsprechenden Parameter.

Andere Tipps

Ich würde denken, dass Ihr Anruf sein müsse:

var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4) });

Es sei denn natürlich, es ist , dass in diesem Fall die Antwort ist nicht sofort ersichtlich.

Obwohl ich hasse printf-ähnliche Debuggen ...

public static void foo(Type t, params object[] p)
{
    System.Diagnostics.Debug.WriteLine("<---- foo");
    foreach(System.Reflection.ConstructorInfo ci in t.GetConstructors())
    {
        System.Diagnostics.Debug.WriteLine(t.FullName + ci.ToString());
    }
    foreach (object o in p)
    {
        System.Diagnostics.Debug.WriteLine("param:" + o.GetType().FullName);
    }
    System.Diagnostics.Debug.WriteLine("foo ---->");
}
// ...
foo(designerAttribute.Designer, new DelayComposite(4));
var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));

Was bedeutet, dass Druck im Ausgabefenster des Visual Studio?

Wenn Sie diesen contructor nennen ...

public DelayCompositeDesigner(DelayComposite CompositeObject)

... nur diese verwenden:

var designer = Activator.CreateInstance(typeof(DelayCompositeDesigner), new DelayComposite(4));

oder

var designer = Activator.CreateInstance<DelayCompositeDesigner>(new DelayComposite(4));

Ich hatte ein ähnliches Problem, aber mein Problem der Sichtbarkeit des Konstrukteurs zurückzuführen war. Dieser Stack-Überlauf half mir:

Instanziierungsanwendung einen Konstruktor mit Parametern in einem interne Klasse mit Reflexion

entdeckte ich einen anderen Weg, um eine Instanz eines Objekts zu schaffen, ohne den Konstruktor aufrufen überhaupt während eine weitere Frage auf SF beantworten .

Im System.Runtime.Serialization Namensraum gibt es eine Funktion FormatterServices.GetUninitializedObject (Typ) , die ein Objekt erstellen, ohne Konstruktor aufrufen.

Wenn Sie an dieser Funktion in Reflector schauen sehen Sie es ein externes Gespräch. Ich weiß nicht, wie schwarze Magie geschieht tatsächlich unter der Haube. Aber ich habe mich selbst beweisen, dass der Konstruktor aufgerufen wurde nie aber das Objekt instanziiert wurde.

Sie können folgende Überlastung CreateInstance verwenden:

public static Object CreateInstance(
    Type type,
    Object[] args
)

Und in Ihrem Fall würde es sein (glaube ich):

var designer = Activator.CreateInstance(
    typeof(DelayCompositeDesigner), 
    new object[] { new DelayComposite(4) } 
);

Ich fand eine Lösung für das Problem, mich mit dem gleichen Problem zu kämpfen habe.

Hier ist mein Aktivator:

private void LoadTask(FileInfo dll)
    {
        Assembly assembly = Assembly.LoadFrom(dll.FullName);

        foreach (Type type in assembly.GetTypes())
        {
            var hasInterface = type.GetInterface("ITask") != null;

            if (type.IsClass && hasInterface)
            {
                var instance = Activator.CreateInstance(type, _proxy, _context);
                _tasks.Add(type.Name, (ITask)instance);
            }
        }
    }

Und hier ist meine Klasse zu aktivieren, beachten Sie, dass ich den Konstruktor params auf Objekte ändern musste, die einzige Art, wie ich es die Arbeit könnte.

public class CalculateDowntimeTask : Task<CalculateDowntimeTask>
{
    public CalculateDowntimeTask(object proxy, object context) : 
        base((TaskServiceClient)proxy, (TaskDataDataContext)context) { }

    public override void Execute()
    {
        LogMessage(new TaskMessage() { Message = "Testing" });
        BroadcastMessage(new TaskMessage() { Message = "Testing" });
    }
}

Wenn ich auf dieses Problem gestoßen, ich wurde mit einem Verfahren, das die Parameterliste zurück Activator.CreateInstance zu stecken und es hat eine andere Anzahl von Argumenten als der Konstruktor des Objekts I zu schaffen versuchen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top