Erstellen von Klassen-Instanz in der Montage von string name
Ich bin mir nicht sicher, ob dies möglich ist, und ich bin ganz neu mit Baugruppen in C#.NET.
Was ich tun möchte, ist das erzeugen einer Instanz einer Klasse geliefert, wenn der string den Namen der Klasse. So etwas wie dieses:
using MyAssembly;
namespace MyNameSpace
{
Class MyClass
{
int MyValue1;
int MyValue2;
public MyClass(string myTypeName)
{
foreach(Type type in MyAssembly)
{
if((string)type == myTypeName)
{
//create a new instance of the type
}
}
AssignInitialValues(//the type created above)
}
//Here I use an abstract type which the type above inherits from
private void AssignInitialValues(AbstractType myClass)
{
this.value1 = myClass.value1;
this.value2 = myClass.value2;
}
}
}
Natürlich können Sie strings vergleichen, um Arten, aber es zeigt, was ich versuche zu tun: erstellen Sie einen Typ gefunden, der in einer anderen assembly, die aus einem string geliefert.
Irgendwelche Gedanken?
EDIT:
Nach dem Versuch:
var myObject = (AbstractType) Activator.CreateInstance(null, myTypeName);
AssignInitialValues(myObject);
Bekomme ich eine Reihe von Fehlern:
- Inkonsistent accessibility: parameter type 'MyAssembly.AbstractType' ist weniger zugreifbar als Methode " MyNameSpace.MyClass.AssignInitialValues(MyAssembly.AstractType)'
- 'MyAssembly.AstractType' unzugänglich ist aufgrund von Schutz-Niveau
- Der Typ oder namespace-name 'MyAssembly" konnte nicht gefunden werden (fehlt eine using-Direktive oder ein Assemblyverweis?)
- Der Typ oder namespace-name 'AbstractType' konnte nicht gefunden werden (fehlt eine using-Direktive oder ein Assemblyverweis?)
Nicht genau sicher, warum es nicht finden können, die Montage, die ich Hinzugefügt habe, einen Verweis auf die assembly, und ich verwenden Sie eine Using-Direktive für den namespace der assembly. Für den Schutz Ebene, es ist Berufung-Klassen (oder eher die Konstruktoren von Klassen), die nur in der öffentlichkeit.
Irgendwelche Hinweise darauf, wo das problem ist?
UPDATE:
Nach der Suche durch mehrere Beiträge auf SO stieß ich auf dieses: https://stackoverflow.com/a/1632609/360627
Machen die AbstractType
Klasse öffentlich gelöst ist das Problem der inkonsistenten Zugänglichkeit.
Den neuen compiler, der Fehler ist dieser:
Nicht in Typ " System.- Laufzeit.Remoting.ObjectHandle' zu 'MyAssembly.AbstractType'
Die Linie, auf den es verweist, ist dieses hier:
var myObject = (AbstractType) Activator.CreateInstance(null, myTypeName);
Mit .Unwrap()
bekommen, die mir in der Vergangenheit dieser Fehler und ich denke, es ist der richtige Weg, es zu tun (unsicher). Allerdings, wenn das Programm läuft ich bekomme dann eine TypeLoadException, wenn dieser code aufgerufen wird.
TypeLoadException: Konnte nicht geladen werden Typ 'AbstractType' aus assembly 'MyNameSpace'...
Ich sofort erkennen kann, dass der Typ seine sucht ist richtig, aber die Montage sieht es im Unrecht ist. Suchen Sie den Activator.CreateInstance(String, String)
- Methode ergab, dass die null als erstes argument bedeutet, dass die Methode sucht in der Ausführung der Montage. Dies steht im Widerspruch zu dem erforderlichen Verhalten wie im ursprünglichen post.
Ich habe versucht, mit MyAssembly
als erstes argument aber dies erzeugt den Fehler:
'MyAssembly" ist ein "Namensraum", aber wird verwendet wie eine 'variable'
Ich denke, dass dies wird verursacht durch MyAssembly
nicht einen string. Aber wenn ich versuche 'MyAssembly'
bekomme ich folgenden compiler-Fehler:
- Zu viele Zeichen in Zeichen literal
- Die beste übereinstimmung für die überladene Methode 'System.Activator.CreateInstance(System.ActivationContext, string[])' hat einige ungültige Argumente
- Argument 1: cannot convert from 'char' to 'System.ActivationContext'
- Argument 2: keine Konvertierung von 'string' zu 'string[]'
Scheint mir wie es ist zu versuchen, die falschen überlastung.
Irgendwelche Gedanken auf, wie man dieses Problem beheben?
- Dupe: stackoverflow.com/q/7398147/422353
- Dass eigentlich gar keine Antwort auf meine Frage, denn ich bekomme Fehler wenn ich Versuch, das zu tun. Siehe mein Kommentar auf die Antwort unten.
- Ah, haben Sie vielleicht gesagt, und dann könnten wir arbeiten, starten von dort aus.
- Ich sehe; ich werde nicht vergessen, zu erwähnen, was habe ich mir angeschaut und versucht bereits nächste Zeit habe ich ein problem.
- Hallo Arcadian, jetzt, dass dein post ist wieder geöffnet, sollten Sie entfernen Sie Ihre Antwort von der Frage, Körper und füge es unten als Antwort. Viel Glück! 🙂
- Tun, danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie den vollständig qualifizierten Namen des Typs, Sie brauchen nicht dieses
foreach
Schleife an alle:Gibt es viele Möglichkeiten, zu erfüllen Ihren Bedarf. Nicht die beste Leistung :
Können Sie auch die Arbeit mit diesem:
MyAssembly
.Okay, so ist dies die Antwort. Ich habe es getestet mit echten code und es funktioniert. Ich bin mir nicht sicher, ob es die beste oder die effizienteste Weg. Ich habe von Ihnen positiv bewertet werden die beiden anderen Antworten, weil Sie halfen mir, auf dem richtigen Weg, aber hier ist die vollständige Antwort.
Dauerte drei Tage googeln, auf der Suche durch SO-und MSDN-aber es ist so.
Beachten Sie, dass bei der Instanziierung einer Klasse mit
Activator.CreateInstance(String, String)
den Namen der assembly (der erste parameter) muss die komplette Montage-name nicht nur der name der .dll (bzw .exe-Datei).Den Namen der assembly abgerufen werden können, mithilfe
string assemblyName = Assembly.GetAssembly(typeof(AbstractType)).ToString();
woAbstractType
kann ersetzt werden durch einen Typ, den Sie kennen, enthalten sein und in der Baugruppe definiert.Den Namen eingeben (zweiter parameter) muss ein voll Qualifizierter name, der nicht nur den Namen der Klasse.
Type.AssemblyQualifiedName
) bei Activator.CreateInstance-oder-Typ.GetType. Sonst .Net nicht in der Lage zu finden, die Ihrem Typ.