4

I have the following structure:

abstract class Parent {}


class Child : Parent
{   
    // Member Variable that I want access to:
    OleDbCommand[] _commandCollection;

    // Auto-generated code here
}

Is it possible to use reflection from within the Parent class to access the _commandCollection within the Child class? If not any suggestions on how I can achieve this?

EDIT: Its probably worth mentioning that in the abstract Parent class I plan to use IDbCommand[] to handle the _commandCollection object as not all my TableAdapters will be using OleDb to connect to their respective databases.

EDIT2: For all the comments saying ... just add a property of function to the child class, I can't as its automatically generated by the VS Designer. I really don't want to have to re-do my work every time I change something in the designer!

TK.
  • 46,577
  • 46
  • 119
  • 147
  • 5
    wow. that's a BIG code smell. why not put the `_commandCollection` in the parent, and type it as `IDbCommand[]`? then you have what you want, you just cast up in the child class. – Matt Ellen Nov 04 '10 at 14:37
  • @TK I would suggest you to check out your code architecture. This situation happens if there is a missing controller class. – honibis Nov 04 '10 at 15:03
  • TK - I can relate to your problem. MS has a habit of setting private, things in generated code that really need to be accessed from derived classes. I'm going to be using this for something similar. – shindigo Feb 10 '12 at 20:07
  • As an example of needing a solution for non-owned classes, Microsoft's [System.ComponentModel.DataAnnotations.ValidationAttribute](https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/ValidationAttribute.cs,78e76a9eac947a00) has many private members that should have been available for extension. There is a real and practical need to access "private" things when the design is broken. – Suncat2000 Sep 30 '20 at 21:23

2 Answers2

11
// _commandCollection is an instance, private member
BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;

// Retrieve a FieldInfo instance corresponding to the field
FieldInfo field = GetType().GetField("_commandCollection", flags);

// Retrieve the value of the field, and cast as necessary
IDbCommand[] cc =(IDbCommand[])field.GetValue(this);

Array covariance should ensure that the cast is successful.

I assume some designer will be generating the subclasses? Otherwise, a protected property is probably what you're looking for.

Ani
  • 111,048
  • 26
  • 262
  • 307
1

It's possible, though it's a decidedly bad idea.

    var field = GetType().GetField("_commandCollection", BindingFlags.Instance | BindingFlags.NonPublic);

I think what you really want to do is provide a method for the child classes to provide the parent with the required data:

protected abstract IEnumerable<IDBCommand> GetCommands();
Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
  • I realise that in most cases private really means 'hands off don't touch', but in this case I'm trying to have a single solution to allow all my (100+) Table Adapters to use this generic piece of code rather than creating and maintaining 100+ partial classes. – TK. Nov 04 '10 at 14:39