• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

VB.net - accessing the data fields of a class

blahblah99

Platinum Member
I'm not a vb.net programmer but I have a small task to do that's giving me some problems and was wondering if anyone can provide some help.

I have a class that retrieves data from a database. The data gets stored in the class's data fields, but they are not exposed. Adding the class to a watch list shows the data fields, but they aren't accessible.

Is there any way to retrieve the data field by using some tricks?

For example, the code goes something like:

Dim obj as widget
Dim color as string

color = obj.Foreground 'invalid and will not compile because Foreground isn't available.

However, if obj is added to the watch list, Foreground will show up and contains "Red"


Edit: Forgot to mention that the class is part of a compiled DLL, which I don't have source code to so I can't just make the data field public.
 
You could try to get the value using reflection but it probably won't work. You really need to change the obj source code.
 
Just to start with a disclaimer: private fields are usually private for a good reason. At the very least, it's an indication that the maker of the class reserves the right to change the field on a whim and expect that the change will have no effect on anything outside of the class. Plus, using the following hack to to get at private fields will look ugly to other people who read your code. Put in some comments to explain why it's necessary.

Sorry the following is in C#. I've pretty much forgotten VB.Net syntax and I don't have any VB.Net IDE on hand right now.

 
Well that doesn't look too readable. This should be at least passable:

using System;
using System.Reflection;

class Program {
public class SomeClass {
/// <summary>
/// A private field
/// </summary>
private string _value = "looks like it works";

/// <summary>
/// A private property
/// </summary>
private string Value {
get {
return _value;
}
set {
_value = value;
}
}
}

static void Main(string[] args) {
// Instantiate an object which we're going to inspect later via reflection
object obj = new SomeClass();
// Get the type of the object
Type type = obj.GetType();

// Get information about the private field we're interested in
FieldInfo fi = type.GetField("_value", BindingFlags.NonPublic | BindingFlags.Instance);
// Use reflection to retrieve the value
string fieldValue = fi.GetValue(obj) as string;
// Print value to command line
Console.WriteLine(fieldValue);

// Get information about the private property we're interested in
PropertyInfo pi = type.GetProperty("Value", BindingFlags.NonPublic | BindingFlags.Instance);
// Use reflection to retrieve the value
string propValue = pi.GetValue(obj, null) as string;
// Print value to command line
Console.WriteLine(propValue);
}
}
 
Originally posted by: jthg
Well that doesn't look too readable. This should be at least passable:

using System;
using System.Reflection;

class Program {
public class SomeClass {
/// <summary>
/// A private field
/// </summary>
private string _value = "looks like it works";

/// <summary>
/// A private property
/// </summary>
private string Value {
get {
return _value;
}
set {
_value = value;
}
}
}

static void Main(string[] args) {
// Instantiate an object which we're going to inspect later via reflection
object obj = new SomeClass();
// Get the type of the object
Type type = obj.GetType();

// Get information about the private field we're interested in
FieldInfo fi = type.GetField("_value", BindingFlags.NonPublic | BindingFlags.Instance);
// Use reflection to retrieve the value
string fieldValue = fi.GetValue(obj) as string;
// Print value to command line
Console.WriteLine(fieldValue);

// Get information about the private property we're interested in
PropertyInfo pi = type.GetProperty("Value", BindingFlags.NonPublic | BindingFlags.Instance);
// Use reflection to retrieve the value
string propValue = pi.GetValue(obj, null) as string;
// Print value to command line
Console.WriteLine(propValue);
}
}

Thanks, that's precisely the info I needed to get going!

The private field that I am trying to access is strictly for read purposes, which the original coders might have forgotten to expose.
 
I should mention that accessing fields using reflection is a couple hundred times slower than reading a (public) field directly. If you really need it to be faster, there is another way to do it which has no performance penalty, but involves generating CIL at runtime.
 
If the class isn't sealed and the parts are protected instead of just private, perhaps you can make your own class that inherits from the base class, and expose it there.
 
Back
Top