PC Review


Reply
Thread Tools Rate Thread

base class cast problem

 
 
mp
Guest
Posts: n/a
 
      21st Jan 2011
my first attempt to use a base class and subType (if that's the correct
terminology)
defined in Investment.cs:
class Investment
class Stock : Investment
class StockListCollection : List<Stock > { }

definted in view
(defined in Iview.cs interface which view implements)
StockListCollection StockWatchChoiceList { get; set; }

in presenter i'm trying to serialize a StockListCollection from the view
the serialize code takes an argument of List<Investment>
so since StockListCollection is a List<Stock >
and Stock is a Investment
I thought that would work...either i can't 'pass through' from base class to
subclass like that
or something else is wrong in my code or definitions

the signature for the serializing code
public static class XMLInvestmentStore
{
public static void StoreInvestmentChoices ( List<Investment>
InvestmentChoices, string fileName )
{...}

i get the following errors:

first i tried this line
XMLInvestmentStore.StoreInvestmentChoices (
this._mView.StockWatchChoiceList, stockWatchFilename );

and got this error
//Argument '1': cannot convert from
'Investments.Model.StockListCollection' to
'System.Collections.Generic.List<Investments.Model.Investment>'

so i thought i needed a specific cast...so i tried this:
XMLInvestmentStore.StoreInvestmentChoices (
(List<Investment>)this._mView.StockWatchChoiceList, stockWatchFilename );
there i *think* i'm casting a StockListCollection to a List<Investment>???
it's base class???

so then i thought maybe i have to cast stock to investment so i tried
XMLInvestmentStore.StoreInvestmentChoices (
(List<(Investment)Stock>)this._mView.StockWatchChoiceList,
stockWatchFilename );
but apparently you can't "cast inside of another cast"

also tried
XMLInvestmentStore.StoreInvestmentChoices (
(List<Stock>)this._mView.StockWatchChoiceList, stockWatchFilename )
but i get this error
Argument '1': cannot convert from
'System.Collections.Generic.List<Investments.Model.Stock>' to
'System.Collections.Generic.List<Investments.Model.Investment>'

but a Stock Is an Investment so i don't know why I can't make that cast?

at least the error msgs keep changing...so it keeps things interesting...:-)
anyone feel like helping shortcut my trial and error?

thanks
mark



 
Reply With Quote
 
 
 
 
Arne Vajhøj
Guest
Posts: n/a
 
      21st Jan 2011
On 21-01-2011 15:06, mp wrote:
> my first attempt to use a base class and subType (if that's the correct
> terminology)
> defined in Investment.cs:
> class Investment
> class Stock : Investment
> class StockListCollection : List<Stock> { }
>
> definted in view
> (defined in Iview.cs interface which view implements)
> StockListCollection StockWatchChoiceList { get; set; }
>
> in presenter i'm trying to serialize a StockListCollection from the view
> the serialize code takes an argument of List<Investment>
> so since StockListCollection is a List<Stock>
> and Stock is a Investment
> I thought that would work...either i can't 'pass through' from base class to
> subclass like that
> or something else is wrong in my code or definitions


X sub class of Y does not mean that List<X> is assignable
to List<Y>.

For good reasons. You can add a Z which is also a sub class
of Y to a List<Y>.

You may look at the new C#/.NET 4.0 where you can restrict
usage to allow something similar to this for interfaces.

Google "C# 4.0 covariance". But it will not work in your
case, because it is only for interfaces and IList does
not use the feature either.

I am pretty sure that you want a List<Investment>.

Arne

 
Reply With Quote
 
Jeff Johnson
Guest
Posts: n/a
 
      21st Jan 2011
"mp" <(E-Mail Removed)> wrote in message
news:ihcp10$3d6$(E-Mail Removed)...

> Argument '1': cannot convert from
> 'System.Collections.Generic.List<Investments.Model.Stock>' to
> 'System.Collections.Generic.List<Investments.Model.Investment>'
>
> but a Stock Is an Investment so i don't know why I can't make that cast?


I JUST happened to read a nice analogy for this a couple of hours ago, so
let me share the link. (It's a Java tutorial, but the concepts are the
same.)

http://download.oracle.com/javase/tu...subtyping.html

Read the part about "cages" in the second half.


 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      21st Jan 2011
On 21-01-2011 15:55, Jeff Johnson wrote:
> "mp"<(E-Mail Removed)> wrote in message
> news:ihcp10$3d6$(E-Mail Removed)...
>
>> Argument '1': cannot convert from
>> 'System.Collections.Generic.List<Investments.Model.Stock>' to
>> 'System.Collections.Generic.List<Investments.Model.Investment>'
>>
>> but a Stock Is an Investment so i don't know why I can't make that cast?

>
> I JUST happened to read a nice analogy for this a couple of hours ago, so
> let me share the link. (It's a Java tutorial, but the concepts are the
> same.)
>
> http://download.oracle.com/javase/tu...subtyping.html
>
> Read the part about "cages" in the second half.


ArrayList<Investment> lst = new ArrayList<Stock>();

will not compile in Java, but:

ArrayList<? extends Investment> lst = new ArrayList<Stock>();

actually compiles in Java.

(in this particular form it is rather useless, but it can
have its usage)

Arne

 
Reply With Quote
 
Jeff Johnson
Guest
Posts: n/a
 
      21st Jan 2011
"Arne Vajhøj" <(E-Mail Removed)> wrote in message
news:4d39f5c6$0$23754$(E-Mail Removed)...

> ArrayList<Investment> lst = new ArrayList<Stock>();
>
> will not compile in Java, but:
>
> ArrayList<? extends Investment> lst = new ArrayList<Stock>();
>
> actually compiles in Java.
>
> (in this particular form it is rather useless, but it can
> have its usage)


Right, and that is mentioned. (Basically, you can READ from the collection
but not change it.)


 
Reply With Quote
 
mp
Guest
Posts: n/a
 
      22nd Jan 2011

"Arne Vajhøj" <(E-Mail Removed)> wrote in message
news:4d39ebab$0$23764$(E-Mail Removed)...
> On 21-01-2011 15:06, mp wrote:
>> my first attempt to use a base class and subType (if that's the correct
>> terminology)
>> defined in Investment.cs:
>> class Investment
>> class Stock : Investment
>> class StockListCollection : List<Stock> { }
>>
>> definted in view
>> (defined in Iview.cs interface which view implements)
>> StockListCollection StockWatchChoiceList { get; set; }
>>
>> in presenter i'm trying to serialize a StockListCollection from the view
>> the serialize code takes an argument of List<Investment>
>> so since StockListCollection is a List<Stock>
>> and Stock is a Investment
>> I thought that would work...either i can't 'pass through' from base class
>> to
>> subclass like that
>> or something else is wrong in my code or definitions

>
> X sub class of Y does not mean that List<X> is assignable
> to List<Y>.
>
> For good reasons. You can add a Z which is also a sub class
> of Y to a List<Y>.
>
> You may look at the new C#/.NET 4.0 where you can restrict
> usage to allow something similar to this for interfaces.
>
> Google "C# 4.0 covariance". But it will not work in your
> case, because it is only for interfaces and IList does
> not use the feature either.
>
> I am pretty sure that you want a List<Investment>.
>
> Arne
>


i tried the following and got this error:
{"The type Investments.Model.Stock was not expected.
Use the XmlInclude or SoapInclude attribute to specify types that are not
known statically."}

public static void StoreInvestmentList ( List<Investment> objectsList,
string fileName )
{
XmlSerializer serializer = null;
try
{
// Create our XML file to hold the serialized data.
using (FileStream fStream = new FileStream ( fileName,
FileMode.Create ))
{
try
{
serializer = new XmlSerializer ( typeof (
List<Investment> ) );
serializer.Serialize ( fStream, objectsList );
}
catch (Exception ex)
{
Debug.Print ( "Unable to Store objects in list...Problem
with XmlSerializer " );
Debug.Print ( "objectsList name {0}", objectsList.ToString
( ) );

Debug.Print ( ex.Message );
throw;
}
}
}
catch (Exception ex)
{
Debug.Print ( "Unable to StoreList of objects...Problem with
FileStream <" + fileName + ">" );
Debug.Print ( ex.Message );
throw;
}
Debug.Print ( "Objects stored in " + fileName );
}
}

*** calling code ***
private void btnGetData_Click(object sender, EventArgs e)
{
List< Investment > testlst = new List<Investment > ( );
for (int i = 0; i < 5; i++)
{ testlst.Add ( new Stock ( "Test " + i.ToString
( ),"Tick"+i.ToString() ) ); }
XMLStoreList.StoreInvestmentList ( testlst ,"TestListStore.xml");
}


*** typedefs ***
[Serializable ( )]
public class Investment {
public Investment()
{ }
public Investment(string name)
{
_name = name;
}
....}
[Serializable ( )]
public class Stock : Investment
{private string _ticker;
public Stock ( ) : base ( ) { }//<<<serialize requires parameterless
ctor
public Stock ( string name, string ticker )
: base ( name )
{
_ticker = ticker;
}
public string Ticker { get { return _ticker; } set { _ticker =
value; } }
}


 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      22nd Jan 2011
On 21-01-2011 20:52, mp wrote:
> "Arne Vajhøj"<(E-Mail Removed)> wrote in message
> news:4d39ebab$0$23764$(E-Mail Removed)...
>> On 21-01-2011 15:06, mp wrote:
>>> my first attempt to use a base class and subType (if that's the correct
>>> terminology)
>>> defined in Investment.cs:
>>> class Investment
>>> class Stock : Investment
>>> class StockListCollection : List<Stock> { }
>>>
>>> definted in view
>>> (defined in Iview.cs interface which view implements)
>>> StockListCollection StockWatchChoiceList { get; set; }
>>>
>>> in presenter i'm trying to serialize a StockListCollection from the view
>>> the serialize code takes an argument of List<Investment>
>>> so since StockListCollection is a List<Stock>
>>> and Stock is a Investment
>>> I thought that would work...either i can't 'pass through' from base class
>>> to
>>> subclass like that
>>> or something else is wrong in my code or definitions

>>
>> X sub class of Y does not mean that List<X> is assignable
>> to List<Y>.
>>
>> For good reasons. You can add a Z which is also a sub class
>> of Y to a List<Y>.
>>
>> You may look at the new C#/.NET 4.0 where you can restrict
>> usage to allow something similar to this for interfaces.
>>
>> Google "C# 4.0 covariance". But it will not work in your
>> case, because it is only for interfaces and IList does
>> not use the feature either.
>>
>> I am pretty sure that you want a List<Investment>.

>
> i tried the following and got this error:
> {"The type Investments.Model.Stock was not expected.
> Use the XmlInclude or SoapInclude attribute to specify types that are not
> known statically."}


Hm.

XmLSerializer can be a bit tricky with stuff like this.

> *** typedefs ***
> [Serializable ( )]


If you insert:

[XmlInclude(typeof(Stick)), XmlInclude(typeof(AnotherInvestment))]

here then it should work but that is not a nice solution.

I can not come up with a better solution though.

> public class Investment {
> public Investment()
> { }
> public Investment(string name)
> {
> _name = name;
> }
> ...}
> [Serializable ( )]
> public class Stock : Investment
> {private string _ticker;
> public Stock ( ) : base ( ) { }//<<<serialize requires parameterless
> ctor
> public Stock ( string name, string ticker )
> : base ( name )
> {
> _ticker = ticker;
> }
> public string Ticker { get { return _ticker; } set { _ticker =
> value; } }
> }


Arne
 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      22nd Jan 2011
On 21-01-2011 21:18, Arne Vajhøj wrote:
> On 21-01-2011 20:52, mp wrote:
>> "Arne Vajhøj"<(E-Mail Removed)> wrote in message
>> news:4d39ebab$0$23764$(E-Mail Removed)...
>>> On 21-01-2011 15:06, mp wrote:
>>>> my first attempt to use a base class and subType (if that's the correct
>>>> terminology)
>>>> defined in Investment.cs:
>>>> class Investment
>>>> class Stock : Investment
>>>> class StockListCollection : List<Stock> { }
>>>>
>>>> definted in view
>>>> (defined in Iview.cs interface which view implements)
>>>> StockListCollection StockWatchChoiceList { get; set; }
>>>>
>>>> in presenter i'm trying to serialize a StockListCollection from the
>>>> view
>>>> the serialize code takes an argument of List<Investment>
>>>> so since StockListCollection is a List<Stock>
>>>> and Stock is a Investment
>>>> I thought that would work...either i can't 'pass through' from base
>>>> class
>>>> to
>>>> subclass like that
>>>> or something else is wrong in my code or definitions
>>>
>>> X sub class of Y does not mean that List<X> is assignable
>>> to List<Y>.
>>>
>>> For good reasons. You can add a Z which is also a sub class
>>> of Y to a List<Y>.
>>>
>>> You may look at the new C#/.NET 4.0 where you can restrict
>>> usage to allow something similar to this for interfaces.
>>>
>>> Google "C# 4.0 covariance". But it will not work in your
>>> case, because it is only for interfaces and IList does
>>> not use the feature either.
>>>
>>> I am pretty sure that you want a List<Investment>.

>>
>> i tried the following and got this error:
>> {"The type Investments.Model.Stock was not expected.
>> Use the XmlInclude or SoapInclude attribute to specify types that are not
>> known statically."}

>
> Hm.
>
> XmLSerializer can be a bit tricky with stuff like this.
>
>> *** typedefs ***
>> [Serializable ( )]

>
> If you insert:
>
> [XmlInclude(typeof(Stick)), XmlInclude(typeof(AnotherInvestment))]
>
> here then it should work but that is not a nice solution.
>
> I can not come up with a better solution though.


Try:

serializer = new XmlSerializer ( typeof (
List<Investment> ), new Type[] { typeof(Stock),
typeof(AnotherInvestment) } );

Arne

 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      22nd Jan 2011
On 21-01-2011 16:38, Jeff Johnson wrote:
> "Arne Vajhøj"<(E-Mail Removed)> wrote in message
> news:4d39f5c6$0$23754$(E-Mail Removed)...
>
>> ArrayList<Investment> lst = new ArrayList<Stock>();
>>
>> will not compile in Java, but:
>>
>> ArrayList<? extends Investment> lst = new ArrayList<Stock>();
>>
>> actually compiles in Java.
>>
>> (in this particular form it is rather useless, but it can
>> have its usage)

>
> Right, and that is mentioned. (Basically, you can READ from the collection
> but not change it.)


One can read, delete and add null. But one can not add
objects.

C# 4.0 interfaces with out type is about the same.

Demo:

using System;
using System.Collections.Generic;

namespace E
{
public class Investment
{

}
public class Stock : Investment
{

}
public class OtherInvestment : Investment
{

}
public interface IROList<out T>
{
T this[int ix]
{
get;
}
}
public class ROList<T,T2> : IROList<T> where T2 : T
{
private IList<T2> real;
public ROList(IList<T2> orig)
{
real = orig;
}
public T this[int ix]
{
get { return real[ix]; }
}
}
public class Program
{
public static void Main(string[] args)
{
//IList<Investment> lst = new List<Stock>();
IROList<Investment> lst1 = new ROList<Investment, Stock>(new
List<Stock>());
IROList<Investment> lst2 = new ROList<Investment,
OtherInvestment>(new List<OtherInvestment>());
Console.ReadKey();
}
}
}

Arne
 
Reply With Quote
 
mp
Guest
Posts: n/a
 
      22nd Jan 2011

"Arne Vajhøj" <(E-Mail Removed)> wrote in message
news:4d3a4041$0$23762$(E-Mail Removed)...
> On 21-01-2011 21:18, Arne Vajhøj wrote:
>> On 21-01-2011 20:52, mp wrote:
>>> "Arne Vajhøj"<(E-Mail Removed)> wrote in message
>>> news:4d39ebab$0$23764$(E-Mail Removed)...
>>>> On 21-01-2011 15:06, mp wrote:
>>>>> my first attempt to use a base class and subType (if that's the
>>>>> correct
>>>>> terminology)

> Try:
>
> serializer = new XmlSerializer ( typeof (
> List<Investment> ), new Type[] { typeof(Stock),
> typeof(AnotherInvestment) } );
>
> Arne
>


woo hoo!!! it works!!!
Thanks very much!
:-)
private void btnGetData_Click(object sender, EventArgs e)
{
Debug.Print ( "Test store investment list" );
List< Investment > testlst = new List<Investment > ( );

for (int i = 0; i < 5; i++)
{ testlst.Add ( new Stock ( "Test " + i.ToString
( ),"Tick"+i.ToString() ) ); }

XMLStoreList.StoreInvestmentList ( testlst ,"TestListStore.xml");

Debug.Print ( "Now try to get it back " );
XMLStoreList.RetrieveInvestmentList (ref testlst,
"TestListStore.xml" );

ReadBackInvestmentList ( testlst );
}
private void ReadBackInvestmentList (List<Investment> testlst )
{
foreach(Stock stock in testlst)
{
Debug.Print("Stock {0}, {1}",stock.Name,stock.Ticker );
}
}

from output:
Test store investment list
Objects stored in TestListStore.xml
Now try to get it back
Stock Test 0, Tick0
Stock Test 1, Tick1
Stock Test 2, Tick2
Stock Test 3, Tick3
Stock Test 4, Tick4


fwiw
public static void StoreInvestmentList ( List<Investment> objectsList,
string fileName )
{
try
{
using (FileStream fStream = new FileStream ( fileName,
FileMode.Create ))
{
try
{
XmlSerializer serializer = new XmlSerializer ( typeof (
List<Investment> ),
new Type[] { typeof(Stock),
typeof(Bond ) } );

serializer.Serialize ( fStream, objectsList );
}
catch (Exception ex)
{
Debug.Print ( "Unable to Store objects in list...Problem
with XmlSerializer " );
Debug.Print ( ex.Message );
throw;
}
}
}
catch (Exception ex)
{
Debug.Print ( "Unable to StoreList of objects...Problem with
FileStream <" + fileName + ">" );
Debug.Print ( ex.Message );
throw;
}
Debug.Print ( "Objects stored in " + fileName );
}//storeInvestmentList

public static void RetrieveInvestmentList ( ref List<Investment>
objectsList, string fileName )
{
try
{
XmlSerializer serializer = new XmlSerializer ( typeof (
List<Investment> ),
new Type[] { typeof ( Stock ), typeof (
Bond ) } );

try
{
using (FileStream fStream = new FileStream ( fileName,
FileMode.Open ))
{
objectsList = (List<Investment>)serializer.Deserialize (
fStream );
}
}
catch (Exception ex)
{
Debug.Print ( "Failed Filestream " + ex.Message );
throw;
}

}
catch (Exception ex)
{
Debug.Print ( "Failed serialize to retrieve " + ex.Message );
throw;
}
}

thank you so much....i would never have figured that out!!!!!
mark


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Cast from parent(base) to son(derived) class? =?ISO-8859-1?Q?=22Andr=E9s_G=2E_Aragoneses_=5B_kno Microsoft C# .NET 11 19th Dec 2006 09:13 PM
can't down cast to base class Lore Leunoeg Microsoft VB .NET 6 28th Oct 2005 03:15 PM
Inheriting a base class - Invalid Cast Exception Chet Cromer Microsoft VB .NET 10 10th Jun 2005 06:28 PM
Cast from base class to a derived class =?Utf-8?B?Sm9l?= Microsoft ADO .NET 1 16th Mar 2005 05:49 PM
base class cast exception =?Utf-8?B?TWljaGVs?= Microsoft C# .NET 1 19th Jan 2005 01:59 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 03:09 AM.