Home > OS >  How to get readonly field value from base generic abstract class
How to get readonly field value from base generic abstract class

Time:10-13

I would like to retrieve readonly field value _classC from base generic abstract class Base<A, B> .

What I have tried

FieldInfo.GetValue must be used certainly, but I can't guess the right parameter.

Thought the instance of the derived class would be okay.

var derived = new Derived();
var baseType = typeof(Base<,>);

var classCField = baseType
  .GetField("_classC", BindingFlags.NonPublic 
    | BindingFlags.Static 
    | BindingFlags.Instance 
    | BindingFlags.FlattenHierarchy);

classCField.GetValue(derived);

The error I get

InvalidOperationException: Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.

Is that even possible?

Type definitions

public interface IBase<A, B>
    where A : class
    where B : class, new()
{
    
}

public class ClassD
{
    
}

public class ClassC
{
    
}

public abstract class Base<A, B> : IBase<A, B>
    where A : class
    where B : class, new()
    {
        private readonly ClassC _classC = new ClassC();
    }

public class Derived : Base<ClassC, ClassD>
{
}

CodePudding user response:

do this :

var field = typeof(Derived).BaseType.GetField("_classC", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
var value = field.GetValue(derived);

CodePudding user response:

Your first error is caused by using an open generic type, you need a constructed one (e.g. Base<ClassC, ClassD>). The next error is that your field isn't static.

As for a repro: it's DotNetFiddle that runs with an outdated trust model regarding reflection. On IdeOne this runs just fine:

public class Test
{
    public static void Main()
    {
        var derived = new Derived();
        var baseType = derived.GetType().BaseType;
        
        var classCField = baseType.GetField("_classC", BindingFlags.NonPublic | BindingFlags.Instance);
                
        Console.WriteLine(classCField.GetValue((Base)derived));
    }
}

public class ClassC
{
}

public abstract class Base//<A, B> : IBase<A, B> where A : class where B : class, new()
{
    private readonly ClassC _classC = new ClassC();
}

public class Derived : Base//<ClassC, ClassD>
{
}
  • Related