Как я могу создать класс во время выполнения в c#? Я хочу, чтобы класс был создан физически в моей файловой системе - PullRequest
0 голосов
/ 03 марта 2020

Я разрабатываю расширение, которое должно создавать классы, в которых только пользователь указывает имя класса и информацию о свойствах, а также некоторые другие, которые я буду расширять позже.

Я также хочу добавить необходимые пространства имен.

Я видел много вопросов, касающихся этого. Я пробовал решения, которые используютражение.emit, CodeDom, но ни одно из них не создает физически классов в моей файловой системе. Есть ли где-нибудь посмотреть или начать с?

Под физическим классом, который я хотел сказать, файлы cs должны отображаться в моей файловой системе. Я говорю о обобщенном c классе, имеющем конструктор и некоторые свойства , функции.

1 Ответ

0 голосов
/ 03 марта 2020

Вы можете использовать Microsoft CodeDom для этого. Ниже приведен пример кода.

Самый простой способ использовать этот код - создать новое «Консольное приложение (. NET Core)» в Visual Studio и просто перезаписать содержимое класса Program (перезаписать). Основной метод). Затем наведите курсор на волнистые линии, и лампочка Visual Studio предложит установить пакет System.CodeDom. Сделайте это для последней версии и добавьте 'using System.CodeDom.Compiler', и он должен скомпилироваться.

Если вы запустите его, он создаст файл с именем MyClass.cs в bin / Debug / netcoreapp3.1 папка с кодом C# для класса со свойством и методом. Имена и типы задаются в приведенном ниже коде, как вы можете видеть.

У Microsoft есть хорошая документация для этого материала: есть страница , которая также показывает, как компилировать и запускать код, сгенерированный в этом путь.

using System;
using System.CodeDom;
using System.CodeDom.Compiler;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            string codeFileName = "MyClass.cs";
            CodeCompileUnit codeCompileUnit = CreateClass();
            CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp");
            IndentedTextWriter tw = new IndentedTextWriter(new System.IO.StreamWriter(codeFileName, false), "    ");
            codeDomProvider.GenerateCodeFromCompileUnit(codeCompileUnit, tw, new CodeGeneratorOptions());
            tw.Close();
        }

        public static CodeCompileUnit CreateClass()
        {
            CodeCompileUnit compileUnit = new CodeCompileUnit();

            CodeNamespace samples = new CodeNamespace("MyNamespace");
            compileUnit.Namespaces.Add(samples);

            CodeTypeDeclaration class1 = new CodeTypeDeclaration("MyClass");
            samples.Types.Add(class1);

            CodeMemberField field1 = new CodeMemberField("System.String", "myField");
            class1.Members.Add(field1);

            CodeMemberProperty property1 = new CodeMemberProperty();
            property1.Name = "MyProperty";
            property1.Type = new CodeTypeReference("System.String");
            property1.Attributes = MemberAttributes.Public;
            property1.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "myField")));
            property1.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "myField"), new CodePropertySetValueReferenceExpression()));
            class1.Members.Add(property1);

            CodeMemberMethod method1 = new CodeMemberMethod();
            method1.Name = "MyMethod";
            method1.ReturnType = new CodeTypeReference("System.String");
            method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "myParameter"));
            method1.Statements.Add(new CodeMethodReturnStatement(new CodeArgumentReferenceExpression("myParameter")));
            class1.Members.Add(method1);

            return compileUnit;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...