converting from base class [quite long]

  • Thread starter Andrzej Kaczmarczyk
  • Start date
A

Andrzej Kaczmarczyk

Hi C# gurus :)

I have a conversion problem.

I have a class that I can't change - it's a DataColumn class;

I have a wrapper class around it.

public MyDataColumn : DataColumn
{
public bool MyFlag;
}

I'd like to do something like this:

DataTable table;
foreach (MyDataColumn column in table.Columns) {
// do something;
}

---

previously I had following construct:

public MyDataColumn {
private DataColumn wrappedColumn;
private MyDataColumn(DataColumn column)
{ this.wrappedColumn = column; }
public static implicit MyDataColumn(DataColumn column)
{ return new MyDataColumn(column); }
}

this way I was able to do the following:

DataTable table;
foreach (DataColumn column in table.Columns) {
MyDataColumn wrapped = column; // no explicit conversion required
// do something
}


----
however I thought that it would be more elegant to inherit directly (as in
the first example). The problem is obvious, the code compile without
problems (there are predefined converters from base to inheriting class when
you define class.) However it will not execute also obvious how can a base
constructor build a child class object.

The solution would be to use the converters, but here the compiler prostest,
that it can't compile a converter when there is one present it doesn't
matter if this is explicit or implicit converter, according to standard
(found somewhere on the web), one cannot define a conversion from a base
class.

Does anyone know how to solve it? If the issue is unsolvable why is it
compiling?


thanks,
CUIN Kaczy
 
J

Jon Skeet [C# MVP]

Andrzej Kaczmarczyk wrote:

The solution would be to use the converters, but here the compiler prostest,
that it can't compile a converter when there is one present it doesn't
matter if this is explicit or implicit converter, according to standard
(found somewhere on the web), one cannot define a conversion from a base
class.

Does anyone know how to solve it? If the issue is unsolvable why is it
compiling?

It is compiling because it's perfectly possible (as far as the compiler
knows) for every element in table.Columns to be a MyDataColumn. It just
happens that it's not true here.

You need to use one of your previous solutions.

Jon
 
O

Ollie Riches

or he could test each column:

DataTable table;
DataColumn column;
MyDataColumn myColumn;

for(int i = 0; i < table.Columns.Count; i++)
{
myColumn = table.Columns as MyDataColumn;
if(myColumn != null)
{
// do stuff
}
}

HTH

Ollie Riches
 
N

Nicholas Paldino [.NET/C# MVP]

Andrzej,

See inline:
I have a wrapper class around it.

public MyDataColumn : DataColumn
{
public bool MyFlag;
}

This isn't a wrapper class. You have extended the DataColumn class. If
you wrapped it, you would have an instance of the DataColumn inside of the
MyDataColumn class.
I'd like to do something like this:

DataTable table;
foreach (MyDataColumn column in table.Columns) {
// do something;
}

The only way to do this is to construct the table from scratch. You
will have to add the instances of your type (MyDataColumn) to the columns
collection (exposed through the Columns property) by calling the overload of
the Add method which takes a DataColumn instance. You should then be able
to fill this DataTable normally.

Later, when accessing the columns, you will have to cast to your type in
order to use your type's specific properties.

Hope this helps.
 
J

Jon Skeet [C# MVP]

Ollie said:
or he could test each column:

DataTable table;
DataColumn column;
MyDataColumn myColumn;

for(int i = 0; i < table.Columns.Count; i++)
{
myColumn = table.Columns as MyDataColumn;
if(myColumn != null)
{
// do stuff
}
}


As I understand it, none of the columns in table.Columns actually
*will* be a MyDataColumn - he just wanted to do the conversion
automatically. Of course, I could have missed what's going on...

Jon
 
O

Ollie Riches

good point :)

Jon Skeet said:
Ollie said:
or he could test each column:

DataTable table;
DataColumn column;
MyDataColumn myColumn;

for(int i = 0; i < table.Columns.Count; i++)
{
myColumn = table.Columns as MyDataColumn;
if(myColumn != null)
{
// do stuff
}
}


As I understand it, none of the columns in table.Columns actually
*will* be a MyDataColumn - he just wanted to do the conversion
automatically. Of course, I could have missed what's going on...

Jon
 
N

Nicholas Paldino [.NET/C# MVP]

Well, the OP could always place his own DataColumn-derived type into the
table in the first place by calling the Add overload on
DataColumnCollection, passing his instance of MyDataColumn in the first
place.

Then, all of the DataColumn instances will be MyDataColumn, and he can
loop through the columns with a foreach as he wishes.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Jon Skeet said:
Ollie said:
or he could test each column:

DataTable table;
DataColumn column;
MyDataColumn myColumn;

for(int i = 0; i < table.Columns.Count; i++)
{
myColumn = table.Columns as MyDataColumn;
if(myColumn != null)
{
// do stuff
}
}


As I understand it, none of the columns in table.Columns actually
*will* be a MyDataColumn - he just wanted to do the conversion
automatically. Of course, I could have missed what's going on...

Jon
 
A

Andrzej Kaczmarczyk

Thx for all aneswer, pretty fast you're :)

Jon, you're right none of the columns are MyDataColumns, I want the
conversion to happen implicitly. IMO however it should not compile, if the
pregenerated converters don't work, and they never will.

.... just tested something ...
DataTable table = new DataTable();
foreach ( int a in table.Columns ) {
// do something
}
this will compile as you say, I was sure it wouldn't :/


anyway,
Nicholas you're right it is an extension not wrapping (the wrapper is the
previous way I did that) I mistyped.

and also you are right about the solution:
I did the following

MyDataTable table
{
DataTable table; // wrapping. implicit conversion, and so on
private List<MyDataColumn> columns; // small optimize
public List<MyDataColumn> Columns{
if (columns == null) {
columns = new List<MyDataColumn>();
foreach (DataColumn col in this.table.Columns) {
this.colums.Add(new MyDataColumn(col)); // explicit conversion don
in single place
}
}
return this.columns;
}
}


this way I am now able to do:
DataTable table;
MyDataTable myTable = table;
foreach (MyDataColumn column in myTable.Columns)
{ // do something }

it DOES move the problem one level higher in the hierarchy but doing the
same steps for table and moving it one further step to DataSet effectively
reduces the number in-code casts to single occurence of

DataSet dataSet;
MyDataSet myDataSet = dataSet;

foreach (MyDataTable table in myDataSet.Tables) {
foreach (MyDataColumn column in table.Columns) {
// do something
}
}

CUIN Kaczy
 
A

Andrzej Kaczmarczyk

Well, the OP could always place his own DataColumn-derived type into
the table in the first place by calling the Add overload on
DataColumnCollection, passing his instance of MyDataColumn in the first
place.
Can't do that. The dataset is a typed one, which means it is pregenerated by
VisualStudio, I am left with some kind of wrapping/inheriting to access them
and extend.
Then, all of the DataColumn instances will be MyDataColumn, and he can
loop through the columns with a foreach as he wishes.
CUIN Kaczy
 
J

Jon Skeet [C# MVP]

Andrzej Kaczmarczyk said:
Thx for all aneswer, pretty fast you're :)

Jon, you're right none of the columns are MyDataColumns, I want the
conversion to happen implicitly. IMO however it should not compile, if the
pregenerated converters don't work, and they never will.

How exactly would the compiler know that? The IEnumerable interface
doesn't say what kind of object it's going to return...
 
A

Andrzej Kaczmarczyk

How exactly would the compiler know that? The IEnumerable interface
doesn't say what kind of object it's going to return...

Good point, I forgot foreach is a layer over IEnumerable. Somehow it occured
to me that it is an array of know types or a list of know types ...

Following that hole, I though that compiler should know all available
conversions ...
Following that hole, why it does create the conversion that can't be correct
(the default conversion cannot create chiold object from base, simply
because it doesn't know what the child will be, for that one would need
explict wrapping)
Following that hole, this mechanism forbids me from doing conversion becuase
there is already conversion that by definition can't be correct.

But yes, you're right...

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