0

I have a class

 Class account {
    Int id ;
 }

I want change it on the run to

 Class account {
     Int id;
     String Name;
 }

And I want to make a object of newly modified class

Is this possible, it would be really helpful

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • You can't just dynamically change a class at execution time. You could *derive* a new class, if you want... – Jon Skeet Jun 05 '16 at 16:43
  • You could possibly do this using castle dynamic proxy [http://kozmic.net/dynamic-proxy-tutorial/](http://kozmic.net/dynamic-proxy-tutorial/) has a good tutorial – pquest Jun 05 '16 at 16:57
  • Will take a look at it –  Jun 05 '16 at 16:58
  • try the `dynamic` type: https://msdn.microsoft.com/en-us/library/dd264736.aspx – Stefan Jun 05 '16 at 17:05

3 Answers3

2

Im not to say that it is impossible, but i would think it is not. Instead you can use Entity Composition like so

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Account a = new Account();
            a.Add("My name is John");
            a.Add(10);

            Console.WriteLine(a.Get<int>(typeof(int)));
            Console.WriteLine(a.Get<string>(typeof(string)));
            Console.ReadLine();
        }
    }

    class Account
    {
        private Dictionary<Type, object> _fields = new Dictionary<Type, object>();

        public void Add(object data)
        {
            _fields.Add(data.GetType(), data);
        }

        public void Remove(Type type)
        {
            _fields.Remove(type);
        }

        public T Get<T>(Type type)
        {
            object data = null;
            if (_fields.TryGetValue(type, out data))
            {
                return (T)data;
            }

            return default(T);
        }
    }
}

You can add any class and retrieve it again. I recommend using a wrapper class even for the simplest fields, otherwise you may prevent yourself from adding more fields of type string. For example you cannot add both a name and a surname, you will have to wrap them in a Name and Surname class. Now if you want to do this during runtime, you will have to also look into using a component framework such as MEF

LuqJensen
  • 310
  • 6
  • 14
  • Wow, looks like it's actually possible –  Jun 05 '16 at 17:11
  • 1
    We have used this very approach above to develop a component based game in Java using the Netbeans Platform. So yes it is indeed possible. Although you should be aware that patterns like this do add some overhead. – LuqJensen Jun 05 '16 at 17:19
1

It seems like it's not possible. However, you could use a different approach:

 var account = new Dictionary<string, object>();
 account["id"] = 42;
 account["name"] = "my name";

Which will probably be more performance-friendly rather than trying to add another field.

Edit

Following @LuqJensen answer, who would have issues if adding, for example, two strings, you could as well do:

class Account
{
    private Dictionary<string, object> _fields = new Dictionary<Type, object>();

    public void Set(string name, object data)
    {
        _fields[name] = data;
    }

    public T Get<T>(string name)
    {
        object data = null;
        if (_fields.TryGetValue(type, out data))
            return (T)data;

        return default(T);
    }
}
Community
  • 1
  • 1
Lonami
  • 5,945
  • 2
  • 20
  • 38
  • Wow, missed that dynamic thing... Thanks –  Jun 05 '16 at 16:55
  • Sorry @ArunprasadesEdathadan I couldn't test it. It isn't working, but I've updated my answer – Lonami Jun 05 '16 at 17:00
  • Not only looks, but **is** impossible. The above just doesn't work (you get runtime exception). – Ivan Stoev Jun 05 '16 at 17:01
  • There must be some way to achieve this –  Jun 05 '16 at 17:03
  • You must add the key/values before accessing. – Stefan Jun 05 '16 at 17:06
  • @Stefan actually, you don't need to use .Add(...) before! – Lonami Jun 05 '16 at 17:07
  • My requirement is actually with the entity framework classes, I have a class, if any changes are made, i need to add few more details like who,time,etc to the object and save it as a another object... –  Jun 05 '16 at 17:08
  • Your better approach is to use a dictionary in my opinion. It's easy to serialize as well. – Lonami Jun 05 '16 at 17:12
  • You missed the text below. I advise to use wrappers for each part. Ie. if Name and Surname could be different classes containing a single string field. Or a single class could have both Name and Surname. The issue is only apparant if you use primitives or non custom classes. I prefer my approach because it has strong type-safety :) – LuqJensen Jun 05 '16 at 17:23
0

If you really need to do this, and I'll always advise against it, you could use the System.Dynamic namespace like so:

dynamic obj = new System.Dynamic.ExpandoObject();
obj.id = 100;
obj.Name = "Something";

Keeping in mind of course that everything that the compiler does on your behalf to keep your code functional, now has to be done at run time.

theB
  • 6,450
  • 1
  • 28
  • 38
  • But I want to add few extra fields dynamically to already written class –  Jun 05 '16 at 17:13
  • 1
    In that case to quote Mr. Skeet: "You can't just dynamically change a class at execution time. You could derive a new class, if you want..." – theB Jun 05 '16 at 17:20
  • Can you give a sample or a link to this , derive dynamically –  Jun 06 '16 at 05:10