views:

209

answers:

2

I have a class C in Assembly A like this:

internal class C
{
  internal static string About_Name {
      get { return "text"; }
  ...
}

I have about 20 such static properties. Is there a way, in an outside assembly, without using friend assembly attribute (.Net reflection only), get class C so I can invoke any of the static string properties like this:

Class C = <some .Net reflection code>;
string expected = C.About_Name;

If that is not possible, a .Net reflection code to get the string property value directly will suffice, but not ideal.

Thanks in advance!

A: 

Yep, it can be done.

It's using Type.GetProperty().

Example:

// Load your assembly and Get the Type
// Assembly load code...
...
// Get type
Type asmType = typeof(C);

// Get internal properties
PropertyInfo pi = asmType.GetProperty("About_Name", BindingFlags.NonPublic | BindingFlags.Static);

// Get Value
var val = pi.GetValue(asmType, null);

This code will return "text" in val, so from there do what you need to with it.

To do this in the sense that you want to, make the code into a method as follows:

    private static string GetString(Type classToCheck, string PropertyName)
    {
        PropertyInfo pi = classToCheck.GetProperty(PropertyName, BindingFlags.NonPublic | BindingFlags.Static);

        object val = null;

        if (pi != null)
            val = pi.GetValue(classToCheck, null);

        return (val != null) ? val.ToString() : string.Empty;
    }

The usage will then be:

string expected = GetString(typeof(C), "About_Name");
Kyle Rozendo
The class itself is internal, so typeof(C) doesn't compile. How do you get Type of a class if you can't reference it in an outside assembly?
Echiban
@Ech - Have you tried reflecting the classes in the same way I did the methods above, using the correct `BindingFlags`?
Kyle Rozendo
+1  A: 

Try this...
Edit: I did not think about just using the type instead of object instance when it was a static property.
Removed var obj = Activator.CreateInstance(type); and use type in prop.GetValue instead of obj.

namespace ClassLibrary1
{
    internal class Class1
    {
        internal static string Test { get { return "test"; } }
    }
    public class Class2
    {

    }
}

var ass = Assembly.GetAssembly(typeof(Class2));
var type = ass.GetType("ClassLibrary1.Class1");
var prop = type.GetProperty("Test", BindingFlags.Static 
    | BindingFlags.NonPublic);
var s = (string)prop.GetValue(type, null);
Jens Granlund
Well, thats pretty much the same as my answer, but remember he's reflecting a static property, so there is no need to instantiate it using `Activator` before getting the value.
Kyle Rozendo
@Kyle Rozendo, you are right about creating the object. The difference is in getting the type.
Jens Granlund