仿制药和铸造 [英] Generics and casting

查看:69
本文介绍了仿制药和铸造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含各种来源数据的xml文件。例如:


< root>

<帐户>

< Id> 1< / Id>

<名称> Somename< /名称>

< City> Somecity< / City>

< ContactPersons>

< ContactPerson>

< Id> 1< / Id>

<名称> Somename< /名称>

< / ContactPerson>

< ContactPerson>

< Id> 2< / Id>

<名称> Somename2< /名称>

< / ContactPerson>

< / ContactPersons>

< /帐户>

< / root> ;


我创建了一个通用的businesscollection(名为BusinessCollection)和一个

的业务类(名为BusinessObject)。然后我创建了一个名为Account的特定

业务类,另一个名为ContactPerson的业务类。它们都来自BusinessObject类。


我使用以下帐户创建了一个businesscollection实例:

BusinessCollection<帐户> collection = new BusinessCollection

< Account>();


我还制作了一个解析器,将xml转换为正确的

商务课程。因此,在上述数据的情况下,我提供了一个

BusinessCollection< Account>的实例。然后我创建帐户对象并将

添加到集合中。这都是使用反射和一些

XPath类完成的。


解析器具有folling方法签名:

public static void ParseToBusinessObjects< T>(BusinessCollection< T>

集合,XPathDocument文档)其中T:BusinessObject


到目前为止一切顺利。但是现在我也想要子集来解析。在xml

数据中,ContactPersons将是我的子集合(属性名称为

相同)。如果我的解析器检测到子集合,它将获得当前的

实例(使用反射)。然后我想再次调用我的输入法

这个集合(递归)


但是当我这样做时:

BusinessCollection < BusinessObject的> subCollection =(BusinessCollection

< BusinessObject>)property.GetValue(instance,null);


我得到一个InvalidCastException,说我无法转换a

BusinessCollection< ContactPerson>和一个

BusinessCollection< BusinessObject>。

当我将其更改为时,它是相同的:

BusinessCollection< T> subCollection =(BusinessCollection< T>)

property.GetValue(instance,null);

我希望有人知道如何解决这个问题,因为它让我疯狂。 />

I have a xml file with data from various sources. For example:

<root>
<Account>
<Id>1</Id>
<Name>Somename</Name>
<City>Somecity</City>
<ContactPersons>
<ContactPerson>
<Id>1</Id>
<Name>Somename</Name>
</ContactPerson>
<ContactPerson>
<Id>2</Id>
<Name>Somename2</Name>
</ContactPerson>
</ContactPersons>
</Account>
</root>

I created a generic businesscollection (named BusinessCollection) and a
business class (named BusinessObject). Then I created a specific
business class named Account en another one called ContactPerson. They
both derive from the BusinessObject class.

I created a instance of a businesscollection with accounts using:
BusinessCollection <Account> collection = new BusinessCollection
<Account>();

I also made a parser that ''translates'' the xml into the correct
business classes. So in case of the data above I provide a instance of
BusinessCollection <Account>. Then I create Account objects and add
them to the collection. This is all done using reflection and some
XPath classes.

The parser has the folling method signature:
public static void ParseToBusinessObjects <T>(BusinessCollection <T>
collection, XPathDocument document) where T : BusinessObject

So far so good. But now I also want subcollections to parse. In the xml
data ContactPersons will be my subcollection (property is named the
same). If my parser detects a subcollection it will get the current
instance (using reflection). I then want to call my entry method again
for this collection (recursive)

However when I do this:
BusinessCollection <BusinessObject> subCollection = (BusinessCollection
<BusinessObject>) property.GetValue(instance, null);

I get a InvalidCastException saying I can''t convert between a
BusinessCollection<ContactPerson> and a
BusinessCollection<BusinessObject>.

Its the same when I change it to :
BusinessCollection <T> subCollection = (BusinessCollection <T>)
property.GetValue(instance, null);
I hope someone knows how to solve this because its driving me nuts.

推荐答案

Alexander van Doormalen写道:
Alexander van Doormalen wrote:
我有一个包含各种来源数据的xml文件。例如:

< root>
<帐户>
< Id> 1< / Id>
<名称> Somename< /名称> < br&>< City> Somecity< / City>
< ContactPersons>
< ContactPerson>
< Id> 1< / Id>
<名称> Somename< ; /名称>
< / ContactPerson>
< ContactPerson>
< Id> 2< / Id>
<名称> Somename2< /名称>
< / ContactPerson>
< / ContactPersons>
< / Account>
< / root>

我创建了一个通用的businesscollection(名为BusinessCollection)和/或业务类(名为BusinessObject)。然后我创建了一个名为Account的特定商业类,另一个名为ContactPerson的商业类。它们都来自BusinessObject类。

我使用以下方法创建了一个带有帐户的businesscollection实例:
BusinessCollection< Account> collection = new BusinessCollection
< Account>();

我还制作了一个解析器,将xml翻译成正确的业务类。因此,在上述数据的情况下,我提供了一个
BusinessCollection< Account>的实例。然后我创建帐户对象并将它们添加到集合中。这都是使用反射和一些
XPath类完成的。

解析器具有folling方法签名:
public static void ParseToBusinessObjects< T>(BusinessCollection< T>
集合,XPathDocument文档)其中T:BusinessObject

到目前为止一切顺利。但是现在我也想要子集来解析。在
xml数据中,ContactPersons将是我的子集合(属性名称
相同)。如果我的解析器检测到子集合,它将获得
当前实例(使用反射)。然后我想再次为这个集合调用我的条目
方法(递归)

然而,当我这样做时:
BusinessCollection< BusinessObject> subCollection =
(BusinessCollection< BusinessObject>)property.GetValue(instance,
null);

我得到一个InvalidCastException,说我不能在
BusinessCollection< ContactPerson>和/或BusinessCollection< BusinessObject>。

当我将其更改为时,它是相同的:
BusinessCollection< T> subCollection =(BusinessCollection< T>)
property.GetValue(instance,null);
I have a xml file with data from various sources. For example:

<root>
<Account>
<Id>1</Id>
<Name>Somename</Name>
<City>Somecity</City>
<ContactPersons>
<ContactPerson>
<Id>1</Id>
<Name>Somename</Name>
</ContactPerson>
<ContactPerson>
<Id>2</Id>
<Name>Somename2</Name>
</ContactPerson>
</ContactPersons>
</Account>
</root>

I created a generic businesscollection (named BusinessCollection) and
a business class (named BusinessObject). Then I created a specific
business class named Account en another one called ContactPerson. They
both derive from the BusinessObject class.

I created a instance of a businesscollection with accounts using:
BusinessCollection <Account> collection = new BusinessCollection
<Account>();

I also made a parser that ''translates'' the xml into the correct
business classes. So in case of the data above I provide a instance of
BusinessCollection <Account>. Then I create Account objects and add
them to the collection. This is all done using reflection and some
XPath classes.

The parser has the folling method signature:
public static void ParseToBusinessObjects <T>(BusinessCollection <T>
collection, XPathDocument document) where T : BusinessObject

So far so good. But now I also want subcollections to parse. In the
xml data ContactPersons will be my subcollection (property is named
the same). If my parser detects a subcollection it will get the
current instance (using reflection). I then want to call my entry
method again for this collection (recursive)

However when I do this:
BusinessCollection <BusinessObject> subCollection =
(BusinessCollection <BusinessObject>) property.GetValue(instance,
null);

I get a InvalidCastException saying I can''t convert between a
BusinessCollection<ContactPerson> and a
BusinessCollection<BusinessObject>.

Its the same when I change it to :
BusinessCollection <T> subCollection = (BusinessCollection <T>)
property.GetValue(instance, null);




这不是支持的。它被称为协方差,并且在.NET泛型中不支持

。 BusinessCollection< BusinessObject的>不是超级类型

的BusinessCollection<联系>,即使它看起来像它。

这就是演员表演失败的原因。
你可以轻松解决它。实现一个接口。接口是

如果泛型类型描述符

发生变化,这是进行泛型编程的一般方法。因此,在您的BusinessCollecttion< T>上,您实施了

IBusinessCollection。这是一个非通用的界面,使用相同的

方法。


你现在可以这样做:

IBusinessCollection subCollection =

(IBusinessCollection)property.Getvalue(instance,null);


并再次调用你的代码。


Frans

-

------------------------------- -----------------------------------------

铅LLBLGen Pro的开发人员,.NET的高效O / R映射器

LLBLGen Pro网站: http://www.llblgen.com

我的.NET博客: http://weblogs.asp.net/fbouma

Microsoft MVP(C#)

-------- -------------------------------------------------- --------------



This isn''t supported. It''s called covariance, and that''s not supported
in .NET generics. BusinessCollection<BusinessObject> isn''t a supertype
of BusinessCollection<Contact>, even though it might look like it.
That''s why casts fail.

You can solve it easily though. Implement an interface. Interfaces are
a general way to do generic programming if the generic type descriptor
changes. So, on your BusinessCollecttion<T>, you implement
IBusinessCollection. That''s a non-generic interface, with the same
methods.

You can now do:
IBusinessCollection subCollection =
(IBusinessCollection)property.Getvalue(instance, null);

and call your code again.

Frans
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------


Frans Bouma [C#MVP]< pe ************ ******@xs4all.nl>写道:
Frans Bouma [C# MVP] <pe******************@xs4all.nl> wrote:
当我将其更改为时,它是相同的:
BusinessCollection< T> subCollection =(BusinessCollection< T>)
property.GetValue(instance,null);
Its the same when I change it to :
BusinessCollection <T> subCollection = (BusinessCollection <T>)
property.GetValue(instance, null);



这不受支持。它被称为协方差,并且在.NET泛型中不支持
。 BusinessCollection< BusinessObject的>虽然它可能看起来像它,但它并不是BusinessCollection< Contact>的超级类型。
这就是演员表演失败的原因。



This isn''t supported. It''s called covariance, and that''s not supported
in .NET generics. BusinessCollection<BusinessObject> isn''t a supertype
of BusinessCollection<Contact>, even though it might look like it.
That''s why casts fail.




只是一个小小的修正 - 它在C#泛型中不受支持。显然

..NET本身同时支持协方差和逆变,但C#没有b $ b暴露它。有关详细信息,请参阅以下链接 - 这是非常有趣的

东西...

http://blogs.msdn.com/rmbyers/archiv...16/375079.aspx


-

Jon Skeet - < sk *** @ pobox.com>
http://www.pobox.com/~skeet 博客: http://www.msmvps.com/jon.skeet

如果回复该群组,请不要给我发邮件太多



Just a tiny correction - it''s not supported in C# generics. Apparently
..NET itself supports both covariance and contravariance, but C# doesn''t
expose it. See the following link for details - it''s fascinating
stuff...

http://blogs.msdn.com/rmbyers/archiv...16/375079.aspx

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


对于那些不可能的事情:(。我希望它会出现在这个特性中。


因为使用接口isn因为各种原因(比如

内部方法需要在对象上调用等),所以我可能会这样做。所以我通过创建一个来解决'b $''期望普通对象的内部方法。

然后我使用reflec调用该集合上的Add方法(

作为对象传递)


MethodInfo info = collection.GetType()。GetMethod("添加);

object [] paramaters = new object [1];

paramaters [0] = businessObject;


info.Invoke(集合,参数);


不是一个非常干净的方式,但它现在可以工作。


Thnx伙伴们的帮助!

To bad thats not possible yet :(. I hope it will be in the feature.

Since using interfaces isn''t possibe because of various reasons (like
internal methods that need to be called on the object etc). So I
''solved'' it by creating an internal method that expects a plain object.
I then use reflection to call the Add method on that collection (which
is passed as an object)

MethodInfo info = collection.GetType().GetMethod("Add");
object[] paramaters = new object[1];
paramaters[0] = businessObject;

info.Invoke(collection, paramaters);

Not a very clean way but it works for now.

Thnx guys for the help!


这篇关于仿制药和铸造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆