inheritance and wrapping (long)

  • Thread starter Andrzej Kaczmarczyk
  • Start date
A

Andrzej Kaczmarczyk

Hi

I am experiencing something weird. maybe you could help me.

I have two ineditable classes from outsource libraries: DataColumn and
GridColumn

I have built a wrapper class around DataColumn like this:

public class MyDataColumn {
// wrapped column
protected DataColumn column;
// additional settings
public bool MyFlag;

// hidden constructor
protected MyDataColumn(DataColumn source) {
this.column = source;
this.MyFlag = true;
}
// public converter
public static explicit MyDataColumn(DataColumn source) {
MyDataColumn tmp = source.ExtendedProperties["MyDataColumn"] as
MyDataColumn;
if (tmp == null) {
tmp = new MyDataColumn(source);
source.ExtendedProperties["MyDataColumn"] = tmp;
}
return tmp;
}
}

The purpose of this class is to build a wrapper class and calculate the
extension (MyFlag) upon which store the settings in ExtendedProperties of
the source DataColumn so as long the original DataColumn exists, all calls
to the MyDataColumn will return stored results. With that i can do the
following.

DataColumn column;
// create wrapping
{
MyDataColumn wrappedColumn1 = (MyDataColumn) column;
wrappedColumn1.MyFlag = false;
}
// somewhere else on the same dataColumn
MyDataColumn wrappedColumn2 = (MyDataColumn) column;
if (!wrappedColumn1.MyFlag) {
// <- I am here
}

This had worked excelently until today, when I decided to extend the class
with its child to wrap another class, like this:

public class MyGridColumn : MyDataColumn
{
// another wrapped column
private GridColumn gridColumn;
// more additions
public bool MySecondFlag;
// hidden constructor
protected MyGridColumn(MyDataColumn sourceDataColumn, GridColumn
sourceGridColumn)
: base(sourceDataColumn)
{
this.gridColumn = sourceGridColumn;
this.MySecondFlag = true;
}

// public converter
public static explicit MyGridColumn(GridColumn source) {
MyGridColumn tmp = source.Tag as MyDataColumn; // this class use Tag
objects instead of ExtendedProperties objects array
if (tmp == null) {
DataColumn dataColumn = source.GetDataColumn(); // this method return
the dataColumn used by this gridColumn
tmp = new MyGridColumn(dataColumn, source);
source.Tag = tmp;
}
return tmp;
}
}

Okay, this class' object does basicly the same as above, it wraps around the
GridColumn object, stores itself within it.
However I can't access the inherited property, or to put it otherwise I can,
but they return default values like this:

DataColumn column;
MyDataColumn myColumn = (MyDataColumn) column;
myColumn.MyFlag = false;

GridColumn gridColumn = new gridColumn(column);
MyGridColumn myGridColumn = (MyGridColumn) gridColumn;
myGridColumn.MySecondFlag = false;

the result is that
myColumn.MyFlag = false; // ok
myGridColumn.MyFlag = true; // not ok
myGridColumn.MySecondFlag = false; // ok

if I check via debuger, I can see that values are like above,
if (using debuger) I dig deeper like:
myGridColumn.base.column.Table.Columns[column].ExtendedProperty["MyDataColumn"].MyFlag
I see 'false' which is correct value

if I do the double wrapping instead of inheritance like this:
MyGridColumn {
private MyDataColumn myDataColumn;
private GridColumn gridColumn;

// instead of calling base constructor I do: this.myDataColumn =
(MyDataColumn) gridColumn.GetDataColumn();
}

everything works as expected ie none of the above quirks. but force me to
use longer calls: myGridColumn.myDataColumn.MyFlag instead of
myGridColumn.MyFlag

Can anyone explain this? How to make it work. I have this certain under skin
feeling that I miss something obvious here.

CUIN Kaczy
 
K

Kevin Spencer

I think your title says it all. Can you not inherit these classes?

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.

Andrzej Kaczmarczyk said:
Hi

I am experiencing something weird. maybe you could help me.

I have two ineditable classes from outsource libraries: DataColumn and
GridColumn

I have built a wrapper class around DataColumn like this:

public class MyDataColumn {
// wrapped column
protected DataColumn column;
// additional settings
public bool MyFlag;

// hidden constructor
protected MyDataColumn(DataColumn source) {
this.column = source;
this.MyFlag = true;
}
// public converter
public static explicit MyDataColumn(DataColumn source) {
MyDataColumn tmp = source.ExtendedProperties["MyDataColumn"] as
MyDataColumn;
if (tmp == null) {
tmp = new MyDataColumn(source);
source.ExtendedProperties["MyDataColumn"] = tmp;
}
return tmp;
}
}

The purpose of this class is to build a wrapper class and calculate the
extension (MyFlag) upon which store the settings in ExtendedProperties of
the source DataColumn so as long the original DataColumn exists, all calls
to the MyDataColumn will return stored results. With that i can do the
following.

DataColumn column;
// create wrapping
{
MyDataColumn wrappedColumn1 = (MyDataColumn) column;
wrappedColumn1.MyFlag = false;
}
// somewhere else on the same dataColumn
MyDataColumn wrappedColumn2 = (MyDataColumn) column;
if (!wrappedColumn1.MyFlag) {
// <- I am here
}

This had worked excelently until today, when I decided to extend the class
with its child to wrap another class, like this:

public class MyGridColumn : MyDataColumn
{
// another wrapped column
private GridColumn gridColumn;
// more additions
public bool MySecondFlag;
// hidden constructor
protected MyGridColumn(MyDataColumn sourceDataColumn, GridColumn
sourceGridColumn)
: base(sourceDataColumn)
{
this.gridColumn = sourceGridColumn;
this.MySecondFlag = true;
}

// public converter
public static explicit MyGridColumn(GridColumn source) {
MyGridColumn tmp = source.Tag as MyDataColumn; // this class use Tag
objects instead of ExtendedProperties objects array
if (tmp == null) {
DataColumn dataColumn = source.GetDataColumn(); // this method return
the dataColumn used by this gridColumn
tmp = new MyGridColumn(dataColumn, source);
source.Tag = tmp;
}
return tmp;
}
}

Okay, this class' object does basicly the same as above, it wraps around
the GridColumn object, stores itself within it.
However I can't access the inherited property, or to put it otherwise I
can, but they return default values like this:

DataColumn column;
MyDataColumn myColumn = (MyDataColumn) column;
myColumn.MyFlag = false;

GridColumn gridColumn = new gridColumn(column);
MyGridColumn myGridColumn = (MyGridColumn) gridColumn;
myGridColumn.MySecondFlag = false;

the result is that
myColumn.MyFlag = false; // ok
myGridColumn.MyFlag = true; // not ok
myGridColumn.MySecondFlag = false; // ok

if I check via debuger, I can see that values are like above,
if (using debuger) I dig deeper like:

myGridColumn.base.column.Table.Columns[column].ExtendedProperty["MyDataColumn"].MyFlag
I see 'false' which is correct value

if I do the double wrapping instead of inheritance like this:
MyGridColumn {
private MyDataColumn myDataColumn;
private GridColumn gridColumn;

// instead of calling base constructor I do: this.myDataColumn =
(MyDataColumn) gridColumn.GetDataColumn();
}

everything works as expected ie none of the above quirks. but force me to
use longer calls: myGridColumn.myDataColumn.MyFlag instead of
myGridColumn.MyFlag

Can anyone explain this? How to make it work. I have this certain under
skin feeling that I miss something obvious here.

CUIN Kaczy
 
A

Andrzej Kaczmarczyk

I think your title says it all. Can you not inherit these classes?
quick aneswer, no

longer aneswer in thread
http://www.dotnetnewsgroups.com/newsgroupthread.asp?Search=quite+and+long&ID=164917&NewsgroupID=18

but short summary:
I need to be able to persist the extended object data. Because I use typed
datasets, I have no influence on it's creation, which means that, I have to
accept that my typed DataSet consist of specialised DataTables which consist
of specialised DataColumns.

Now If I do something like this:
MyDataColumn : DataColumn
{
public bool MyFlag;

public MyDataColumn() : base ()
{
this.MyFlag = false;
}
}

I couldn't do
DataTable table;
MyDataColumn column = table.Columns["col1"]; // on the right side I have
DataColumns assigned by generator
I couldn't also:

foreach (MyDataColumn column in table.Columns) {
}

I can't write converter because you can't write converters for related
classes (which is plain stupid constraint btw)

I could do
MyDataColumn column = new MyDataColumn(table.Columns["col1"])

but,
1. this is quite ackward to use
2. the changes wouldn't be persisted

MyDataColumn column1 = new MyDataColumn(table.Columns["col1"])
column1.MyFlag = true;
// later in code (like in another loop through table columns or in temporary
instance when calling subroutines)

MyDataColumn column2 = new MyDataColumn(table.Columns["col1"])
if (column2.MyFlag) {
// I should be here, but I wouldn't with inheritance
}

colum1 and column2 points at two different and unrelated objects. I could of
course store all the data in the ExtendedProperties but this mechanis isn't
universal, isn't typesafe, and use string search which is slow

because both of those objects are using some existing object as a data
source, it is a schoolbook case for wrapping not for inheritance

I'd love to use inheritance here, but can not and was convinced in the
thread I pointed above.

as for this case, I'd like to use inheritance (I've included my attempt in
my previous mail), but the results are weird (the inherited properties
aren't set), and I don't understand why. Again using wrapping helped, but
the syntax is unwieldy.
--
HTH,

Kevin Spencer
Microsoft MVP
.Net Developer
A watched clock never boils.
[snip unnecessary paste]

CUIN Kaczy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top