Ich habe eine Klasse, die so aussieht:
public class Field
{
public string FieldName;
public string FieldType;
}
Und ein Objekt List<Field>
mit Werten:
{"EmployeeID","int"},
{"EmployeeName","String"},
{"Designation","String"}
Ich möchte eine Klasse erstellen, die so aussieht:
Class DynamicClass
{
int EmployeeID,
String EmployeeName,
String Designation
}
Gibt es eine Möglichkeit, dies zu tun?
Ich möchte, dass dies zur Laufzeit generiert wird. Ich möchte keine physische CS-Datei in meinem Dateisystem.
c#
.net
reflection.emit
dynamic-class-creation
Ashwnacharya
quelle
quelle
System.ServiceModel.ChannelFactory<MyDynamicInterface>
Antworten:
Ja, Sie können hierfür den
System.Reflection.Emit
Namespace verwenden. Es ist nicht einfach, wenn Sie keine Erfahrung damit haben, aber es ist sicherlich möglich.Bearbeiten: Dieser Code ist möglicherweise fehlerhaft, aber er gibt Ihnen die allgemeine Vorstellung und hoffentlich einen guten Start in Richtung Ziel.
quelle
Es wird einige Arbeit erfordern, ist aber sicherlich nicht unmöglich.
Was ich getan habe ist:
Microsoft.CSharp.CSharpCodeProvider
(CompileAssemblyFromSource)Activator.CreateInstance
)Auf diese Weise können Sie mit dem bereits bekannten C # -Code umgehen, anstatt MSIL ausgeben zu müssen.
Dies funktioniert jedoch am besten, wenn Ihre Klasse eine Schnittstelle implementiert (oder von einer Basisklasse abgeleitet ist). Wie kann der aufrufende Code (read: compiler) über diese Klasse Bescheid wissen, die zur Laufzeit generiert wird?
quelle
Sie können eine Klasse auch dynamisch mithilfe von DynamicObject erstellen .
Ich speichere alle Klassenfelder
_fields
zusammen mit ihren Typen und Werten in einem Wörterbuch . Mit beiden Methoden können einige der Eigenschaften abgerufen oder festgelegt werden. Sie müssen dasdynamic
Schlüsselwort verwenden, um eine Instanz dieser Klasse zu erstellen.Die Verwendung mit Ihrem Beispiel:
Edit: Und so sieht meine Klasse aus
Field
:quelle
dynamic obj = new DynamicClass(fields){EmployeeId=123456;EmployeeName = "John"; Designation = "Tech Lead";}
es wäre wirklich toll das zu tun.Ich weiß, dass ich diese alte Aufgabe wieder öffne, aber mit c # 4.0 ist diese Aufgabe absolut schmerzlos.
Weitere Informationen finden Sie unter https://www.oreilly.com/learning/building-c-objects-dynamically
quelle
Ich kenne die beabsichtigte Verwendung solcher dynamischer Klassen nicht, und die Codegenerierung und Laufzeitkompilierung kann durchgeführt werden, erfordert jedoch einige Anstrengungen. Vielleicht würden Ihnen anonyme Typen helfen, so etwas wie:
quelle
Field.FieldName
. Die Feldnamen hart codieren zu müssen, macht den Zweck zunichte. Wenn Sie das tun müssen, können Sie auch die Klasse erstellen.Sie möchten sich CodeDOM ansehen . Es ermöglicht das Definieren und Kompilieren von Codeelementen. MSDN zitieren:
quelle
Erstellen Sie basierend auf der Antwort von @ danijels dynamisch eine Klasse in VB.NET:
quelle
Sie können eine Klasse auch dynamisch mithilfe von DynamicExpressions erstellen .
Da 'Wörterbücher kompakte Initialisierer haben und Schlüsselkollisionen verarbeiten, sollten Sie so etwas tun.
Oder Sie möchten möglicherweise einen JSON-Konverter verwenden, um Ihr serialisiertes Zeichenfolgenobjekt in etwas Verwaltbares zu konstruieren.
Verwenden Sie dann System.Linq.Dynamic.
Der Rest verwendet nur System.Reflection.
quelle
Für diejenigen, die eine dynamische Klasse erstellen möchten, nur Eigenschaften (dh POCO) und eine Liste dieser Klasse erstellen. Mit dem später bereitgestellten Code wird eine dynamische Klasse erstellt und eine Liste davon erstellt.
Hier sind die Klassen, die der vorherige Code verwendet.
Hinweis: Sie müssen auch auf die Microsoft.CodeAnalysis.CSharp-Bibliothek verweisen.
quelle
Sie können sich die Verwendung dynamischer Module und Klassen ansehen, die diese Aufgabe erfüllen können. Der einzige Nachteil ist, dass es in der App-Domain geladen bleibt. Mit der verwendeten Version von .NET Framework könnte sich dies jedoch ändern. .NET 4.0 unterstützt sammelbare dynamische Assemblys. Daher können Sie die Klassen / Typen dynamisch neu erstellen.
quelle
Beeindruckend! Vielen Dank für diese Antwort! Ich habe einige Funktionen hinzugefügt, um einen "datatable to json" -Konverter zu erstellen, den ich mit Ihnen teile.
Und im Sub "compileresulttype" habe ich Folgendes geändert:
quelle
Sie können System.Runtime.Remoting.Proxies.RealProxy verwenden. Es ermöglicht Ihnen, "normalen" Code anstelle von Assemblierungsmaterial auf niedriger Ebene zu verwenden.
Ein gutes Beispiel finden Sie in der RealProxy-Antwort auf diese Frage:
Wie fange ich einen Methodenaufruf in C # ab?
quelle
Runtime Code Generation with JVM and CLR
- Peter SestoftArbeiten Sie für Personen, die sich wirklich für diese Art der Programmierung interessieren.
Mein Tipp für Sie ist, dass Sie, wenn Sie etwas deklarieren, versuchen, eine Zeichenfolge zu vermeiden. Wenn Sie also eine Klasse Field haben, ist es besser, die Klasse System.Type zum Speichern des Feldtyps als eine Zeichenfolge zu verwenden. Und um die besten Lösungen zu erzielen, anstatt neue Klassen zu erstellen, versuchen Sie, diejenigen zu verwenden, die FiledInfo erstellt hat, anstatt neue zu erstellen .
quelle