1

In my application, I want to change class B at startup. Here is my code but after executing ModifyClassB(), class B is unchanged. I've attached a sample of the problem, although this is not my final application.

What is the problem with my code? How can I do this?

namespace TestRecompile
{
    class Program
    {
        static void Main(string[] args)
        {
             A test = new A();

            ModifiyClassB();

            test = new A();

            Console.ReadKey();
        }

        static void ModifiyClassB()
        {
            string[] code = {
                "using System; using System.Data;" +
                "namespace TestRecompile"+
                "{" +
                    "public class B " +
                        "{" +
                            "protected int id = 0;"+
                            "public B()"+
                                "{"+
                                    "id = 3;"+
                                "}"+
                        "}" +
                "}"
            };

            CompileAndRun(code);

        }

        static int CompileAndRun(string[] code)
        {
            CompilerParameters CompilerParams = new CompilerParameters();
            string outputDirectory = Directory.GetCurrentDirectory();

            CompilerParams.GenerateInMemory = true;
            CompilerParams.TreatWarningsAsErrors = false;
            CompilerParams.GenerateExecutable = false;
            CompilerParams.CompilerOptions = "/optimize";

            string[] references = { "System.dll", "System.Data.dll" };
            CompilerParams.ReferencedAssemblies.AddRange(references);

            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerResults compile =         provider.CompileAssemblyFromSource(CompilerParams, code);

            if (compile.Errors.HasErrors)
            {
                string text = "Compile error: ";
                foreach (CompilerError ce in compile.Errors)
                {
                    text += "rn" + ce.ToString();
                }
                throw new Exception(text);
            }

            Module module = compile.CompiledAssembly.GetModules()[0];
            Type mt = null;
            MethodInfo methInfo = null;

            if (module != null)
            {
                mt = module.GetType("CodeFromFile.CodeFromFile");
            }

            if (mt != null)
            {
                methInfo = mt.GetMethod("Add");
            }

            if (methInfo != null)
            {
                return (int)methInfo.Invoke(null, new object[] { 5, 10 });
            }

            return -1;
        }
    }

    public class B
    {
        protected int id = 0;
        public B()
        {
            id = 2;
        }
    }

    public class A : B
    {
        public A()
        {
            Console.WriteLine("id value is:" + id);
        }
    }

}
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
chris2626
  • 11
  • 1
  • 2
    You're not modifying `B`, you're constructing a new assembly with a new type, which is coincidentally also called `B`. – ProgrammingLlama Sep 04 '19 at 07:50
  • 3
    This has got to be an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), surely? Please provide more information about what you're trying to do. – ProgrammingLlama Sep 04 '19 at 07:51
  • 1
    If you _do_ need to do this, I believe a library called [Cecil](https://www.mono-project.com/docs/tools+libraries/libraries/Mono.Cecil/) _might_ be helpful. – ProgrammingLlama Sep 04 '19 at 07:57
  • Use cecil like @John mentioned or https://github.com/0xd4d/dnlib – Konrad Sep 04 '19 at 07:58
  • `id = 3` So your real issue seems to be around changing the default value of `id`. In which case, store the default value in a `static` (global) variable. Change the value of the `static` variable, and all _future_ `B` instances will be instantiated appropriately. – mjwills Sep 04 '19 at 08:02

0 Answers0