0

i just wanted to know Is it Possible to expose a private variable in c# ? I know if data of a class is private means is not accessible from outside class. if, yes, then how ?

Chandan Kumar
  • 4,570
  • 4
  • 42
  • 62
  • With or without modifying the class? If you can modify the class you can just expose the variable via a property or method. – Ant P Dec 14 '13 at 23:26

3 Answers3

4

It is possible. Use Reflection for that:

Type type = yourObj.GetType();
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
FieldInfo field = type.GetField("fieldName", flags);
object value = field.GetValue(yourObj);

Reflection allows to read type's metadata at runtime and uncover types internals (fields, propertis etc).

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • hi, can you please help me out with a small sample ? – Chandan Kumar Dec 14 '13 at 23:17
  • @kumarch1 sure, updated answer with sample of getting value of private instance field – Sergey Berezovskiy Dec 14 '13 at 23:18
  • Thank a lot. then how far we can say my data is secure. here is shows it is exposed. Please tell me how can i make this private - i mean complete private - such that no other can access. is it possible? – Chandan Kumar Dec 14 '13 at 23:30
  • 1
    @kumarch1 Private doesn't mean "secure," it just means "not exposed to other classes." You make your data secure by securing it at the source, not by only using it in private fields. – Ant P Dec 14 '13 at 23:34
  • @kumarch1 no, you can't make your data 'completely private' - it's always possible to get them with reflection. But you can make this information very hard to use with [obfuscation](http://stackoverflow.com/questions/337134/what-is-the-best-net-obfuscator-on-the-market?rq=1). – Sergey Berezovskiy Dec 14 '13 at 23:48
  • @Sergey Berezovskiy oh great :) . I was unaware about that. can you please tell me among these obfuscation applications which is good and open source ..means can be accessible through nuget. – Chandan Kumar Dec 14 '13 at 23:56
1

Many more Thanks @Sergey Berezovskiy .

Here i have solved with the help of that.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ExposePrivateVariablesUsingReflection
{
    class Program
    {
        private class MyPrivateClass
        {
            private string MyPrivateFunc(string message)
            {
                return message + "Yes";
            }
        }

        static void Main(string[] args)
        {
            var mpc = new MyPrivateClass();
            Type type = mpc.GetType();

            var output = (string)type.InvokeMember("MyPrivateFunc",
                                        BindingFlags.Instance | BindingFlags.InvokeMethod |
                                        BindingFlags.NonPublic, null, mpc,
                                        new object[] {"Is Exposed private Member ? "});

            Console.WriteLine("Output : " + output);
            Console.ReadLine();
        }
    }
}
Chandan Kumar
  • 4,570
  • 4
  • 42
  • 62
0

You could use reflection to access private variables. However, even though a bit off-topic, I wanted to share something regarding InternalsVisibleTo.

Let's say you have your Domain Objects in an assembly MyExample.DomainObjects and you don't want to put the setters public but you need your service layer to be able to write to them but it is in a separate assembly, you could still use internal setters and avoid reflection:

namespace MyExample.DomainObjects {
    public class MyObject{
        public string MyProp { get; internal set; }
    }
}

You could have your MyExample.ServiceLayer in a separate assembly if you put the following in the MyExample.DomainObjects project's AssemblyInfo.cs

[assembly: InternalsVisibleTo("MyExample.ServiceLayer")]

Then you can call the internal setters in MyExample.DomainObjects from MyExample.ServiceLayer.

Jani Hyytiäinen
  • 5,293
  • 36
  • 45