通用方法 [英] Generic methods

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

问题描述

我对仿制药很新。我有2个通用类:

MyClass< Tand MyOtherClass< T> ;.

MyClass< Thas 2 public Add methods

Add(MyOtherClass< T> ;);

Add(MyOtherClass< Wrapper< T>>); (包装器< Tis另一个类,

包含类型为T的对象)

我有第三个通用类:MyHandler< Twhich包含2个添加
方法和通用方法:

添加(T obj)

{

添加< T>(obj);

}

添加(Wrapper< Tobj)

{

添加< Wrapper< T>>(obj) ;

}

添加< E>(E obj)

{

MyOtherClass< Eobj1 = new MyOtherClass< E>();

MyClass< Tobj2 = new MyClass< T>();

obj2.Add(obj1);

}


编译器抱怨obj2.Add(obj1)无法转换为

MyOtherClass< Eto MyOtherClass< T>


为什么这不起作用?我应该怎么做?


非常感谢你的帮助。

谢谢

Phil

I''m quite new to generics. I have 2 generic classes:
MyClass<Tand MyOtherClass<T>.
MyClass<Thas 2 public Add methods
Add(MyOtherClass<T>);
Add(MyOtherClass<Wrapper<T>>); (Wrapper<Tis another class that
contains an object of type T)

I have a third generic class: MyHandler<Twhich contains 2 Add
methods and a generic method:
Add(T obj)
{
Add<T>(obj);
}
Add(Wrapper<Tobj)
{
Add<Wrapper<T>>(obj);
}
Add<E>(E obj)
{
MyOtherClass<Eobj1 = new MyOtherClass<E>();
MyClass<Tobj2 = new MyClass<T>();
obj2.Add(obj1);
}

The compiler complains about obj2.Add(obj1) that "cannot convert from
MyOtherClass<Eto MyOtherClass<T>"

why doesn''t this work? How should I be doing it?

very grateful for your help.
Thanks
Phil

推荐答案

ph ***** @ googlemail.com 写道:

编译器抱怨obj2.Add(obj1)无法转换为

MyOtherClass< Eto MyOtherClass< T>


为什么这不起作用?我应该怎么做?
The compiler complains about obj2.Add(obj1) that "cannot convert from
MyOtherClass<Eto MyOtherClass<T>"

why doesn''t this work? How should I be doing it?



如果E与T不同,那么传递MyOtherClass< Ein的地方

MyOtherClass< Tisn's合法。即使E和T与

继承相关,也是不允许的,我甚至不会在你的

代码中看到任何暗示它们的内容。


你如何_should_做它,我不确定。这取决于你在这里尝试做什么。为什么方法通用?您发布的代码

无论如何似乎都没有对参数做任何事情。所以它是

不清楚你是如何使用它的。


如果你希望总是使用与T兼容的对象,那么

也许你可以利用它。例如,如果E继承T:


添加< E>(E obj)其中E:T

{

MyOtherClass< ; Tobj1 = new MyOtherClass< T>();

MyClass< Tobj2 = new MyClass< T>();


/ *大概在某个地方,或者在上面的构造函数

或更高版本,你使用obj在某种程度上与上面的基于T的泛型实例有关。在这种情况下,

因为它被限制继承T,你可以使用

obj参数,无论你需要一个T * /


obj2.Add(obj1);

}


很难给出一个很好的具体答案,因为你发布的代码
并没有解释为什么这个方法就是这样的。我们真的不能确定你想要做什么。另一种解决问题的方法是使用E和E。代替T而不是T在方法的每个地方,但是再次,

不知道你为什么用这种方式编写方法,很难知道

是否是合适的答案。 br />

Pete

If E is not the same as T, then passing a MyOtherClass<Ein place of a
MyOtherClass<Tisn''t legal. Even if E and T are related by
inheritance, it''s not allowed, and I don''t even see anything in your
code that suggests they are.

How you _should_ be doing it, I''m not sure. It depends on what you''re
trying to do here. Why is the method generic? The code you posted
doesn''t appear to do anything with the parameter anyway. So it''s
unclear how you are using it.

If you expect to always be using with an object compatible with T, then
perhaps you can take advantage of that. For example, if E inherits T:

Add<E>(E obj) where E : T
{
MyOtherClass<Tobj1 = new MyOtherClass<T>();
MyClass<Tobj2 = new MyClass<T>();

/* Presumably somewhere, either in the above constructors
or later on, you use "obj" in some way related to the
T-based generic instances above. In that context,
because it''s been constrained to inherit T, you can use
the "obj" parameter wherever you''d need a T */

obj2.Add(obj1);
}

It''s difficult to give a nice specific answer, because the code you
posted doesn''t explain why the method is the way it is. We can''t really
tell what it is exactly you want to do. Another way to fix the problem
would be to use "E" instead of "T" everywhere in the method, but again,
without knowing why you wrote the method that way, it''s hard to know if
that''s a suitable answer.

Pete


8月23日,01:18,Peter Duniho< NpOeStPe ... @ NnOwSlPiAnMk.comwrote:
On 23 Aug, 01:18, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.comwrote:

phan ... @ googlemail.com写道:
phan...@googlemail.com wrote:

编译器抱怨obj2.Add(obj1) 无法转换为

MyOtherClass< Eto MyOtherClass< T>
The compiler complains about obj2.Add(obj1) that "cannot convert from
MyOtherClass<Eto MyOtherClass<T>"


为什么这不起作用?我应该怎么做?
why doesn''t this work? How should I be doing it?



如果E与T不同,那么传递MyOtherClass< Ein位置

MyOtherClass< Tisn's合法。即使E和T与

继承相关,也是不允许的,我甚至不会在你的

代码中看到任何暗示它们的内容。


你如何_should_做它,我不确定。这取决于你在这里尝试做什么。为什么方法通用?您发布的代码

无论如何似乎都没有对参数做任何事情。所以它是

不清楚你是如何使用它的。


如果你希望总是使用与T兼容的对象,那么

也许你可以利用它。例如,如果E继承T:


添加< E>(E obj)其中E:T

{

MyOtherClass< ; Tobj1 = new MyOtherClass< T>();

MyClass< Tobj2 = new MyClass< T>();


/ *大概在某个地方,或者在上面的构造函数

或更高版本,你使用obj在某种程度上与上面的基于T的泛型实例有关。在这种情况下,

因为它被限制继承T,你可以使用

obj参数,无论你需要一个T * /


obj2.Add(obj1);

}


很难给出一个很好的具体答案,因为你发布的代码
并没有解释为什么这个方法就是这样的。我们真的不能确定你想要做什么。另一种解决问题的方法是使用E和E。代替T而不是T在方法的每个地方,但是再次,

不知道你为什么用这种方式编写方法,很难知道

是否是合适的答案。 br />

Pete


If E is not the same as T, then passing a MyOtherClass<Ein place of a
MyOtherClass<Tisn''t legal. Even if E and T are related by
inheritance, it''s not allowed, and I don''t even see anything in your
code that suggests they are.

How you _should_ be doing it, I''m not sure. It depends on what you''re
trying to do here. Why is the method generic? The code you posted
doesn''t appear to do anything with the parameter anyway. So it''s
unclear how you are using it.

If you expect to always be using with an object compatible with T, then
perhaps you can take advantage of that. For example, if E inherits T:

Add<E>(E obj) where E : T
{
MyOtherClass<Tobj1 = new MyOtherClass<T>();
MyClass<Tobj2 = new MyClass<T>();

/* Presumably somewhere, either in the above constructors
or later on, you use "obj" in some way related to the
T-based generic instances above. In that context,
because it''s been constrained to inherit T, you can use
the "obj" parameter wherever you''d need a T */

obj2.Add(obj1);
}

It''s difficult to give a nice specific answer, because the code you
posted doesn''t explain why the method is the way it is. We can''t really
tell what it is exactly you want to do. Another way to fix the problem
would be to use "E" instead of "T" everywhere in the method, but again,
without knowing why you wrote the method that way, it''s hard to know if
that''s a suitable answer.

Pete



ok,抱歉,我试图简化。

ObjectHandler< Tis my处理对象的DAL对象处理程序

都来自BaseObject,因此ObjectHandler< Location>,

ObjectHandler< Personetc。

这有选择权添加将对象作为参数的方法。

对象是AddRequest< Locationetc或

AddRequest< Wrapper< Location>等因为有时在我的业务中

Layer I通过包装它将一些信息添加到基本对象。

数据访问层在NUnit测试中工作正常,我要么传递

AddRequest< objector和AddRequest< Wrapper< object>> ;.

我的业务层有一个ObjectManager< Twhere T也是一个BaseObject

所以ObjectManager< Locationetc。在这个经理的Add方法中,

有时候我想把对象不动地传递给DAL所以我

将使用AddRequest< Location>,有时我需要附加更多

信息所以我想使用AddRequest< Wrapper< Location>> ;.


因此公共ObjectManager< T> .Add采用一个对象类型T.然后

有2个受保护的内部AddObject方法,一个带有一个对象$ / b $ b类型为T,一个带有一个Wrapper< Tbecause业务层内部

我可以添加任何一种对象。我试图做的是

调用泛型方法AddObject< E>(E obj),其中此方法将使用AddRequest<
调用DAL。 E>,所以:

ObjectManager< T> .Add(T obj)

{

AddObject< T>(obj);

}

ObjectManager< Wrapper< T>> .Add(Wrapper< Tobj)

{

AddObject< Wrapper< ; T>>(obj);

}


我说得好吗?所以据我所知,如果

AddObject< Eis用类型为T的对象调用,那么对

DAL的调用将使用AddRequest< Twhich将映射重载方法

采用AddRequest< Ttype参数。如果使用Wrapper调用AddObject< Eis

,那么它将使用AddRequest< Wrapper< T>>

将映射到该重载方法。


非常感谢您的帮助。


谢谢

ok, sorry, I was trying to simplify.
ObjectHandler<Tis my DAL object handler dealing with objects that
all derive from a BaseObject so ObjectHandler<Location>,
ObjectHandler<Personetc.
This has a choice of Add Methods that take an object as a parameter.
The object is either AddRequest<Locationetc or
AddRequest<Wrapper<Location>etc because sometimes in my Business
Layer I add some information to the basic object by wrapping it. The
Data Access Layer works fine in NUnit tests where I either pass an
AddRequest<objector an AddRequest<Wrapper<object>>.

My Business Layer has an ObjectManager<Twhere T is also a BaseObject
so ObjectManager<Locationetc. In the Add method of this manager,
sometimes I want to pass the object untouched through to the DAL so I
will use AddRequest<Location>, sometimes I need to attach some more
info so I want to use AddRequest<Wrapper<Location>>.

So the public ObjectManager<T>.Add takes an object of type T. I then
have 2 protected internal AddObject methods, one takes an object of
type T, one takes a Wrapper<Tbecause internal to the Business Layer
I could be adding either kind of object. What I was trying to do then
was call a generic method AddObject<E>(E obj) where this method would
then call down to the DAL using an AddRequest<E>, so:
ObjectManager<T>.Add(T obj)
{
AddObject<T>(obj);
}
ObjectManager<Wrapper<T>>.Add(Wrapper<Tobj)
{
AddObject<Wrapper<T>>(obj);
}

Have I explained it well enough? So as far as I can tell, if
AddObject<Eis called with an object of type T, then the call to the
DAL will use an AddRequest<Twhich will map to the overloaded method
that takes an AddRequest<Ttype parameter. And if AddObject<Eis
called with a Wrapper<Tthen it will use an AddRequest<Wrapper<T>>
which will map to that overloaded method.

Your help is greatly appreciated.

Thanks


ph ***** @ googlemail.com 写道:

[。 ..]

我说得好吗?所以据我所知,如果

AddObject< Eis用类型为T的对象调用,那么对

DAL的调用将使用AddRequest< Twhich将映射重载方法

采用AddRequest< Ttype参数。如果使用Wrapper调用AddObject< Eis

,那么它将使用AddRequest< Wrapper< T>>

将映射到该重载方法。
[...]
Have I explained it well enough? So as far as I can tell, if
AddObject<Eis called with an object of type T, then the call to the
DAL will use an AddRequest<Twhich will map to the overloaded method
that takes an AddRequest<Ttype parameter. And if AddObject<Eis
called with a Wrapper<Tthen it will use an AddRequest<Wrapper<T>>
which will map to that overloaded method.



现在已经晚了,所以也许我没有得到它。但是这就是我认为我理解的:


这里的关键是你不想写两个AddObject()方法,

取一个T,一个取Wrapper< T>。你更希望

有一个AddObject()方法,可以采用T或

Wrapper< T> ;.


这是对的吗?


如果是这样,我认为问题是编译器在错误发生的行b / b $ b没有办法知道T与你知道它的方式相关的是什么。


我玩了一些约束。好的,很多。可能比我应该打扰的b $ b多了。 :)有很多方法可以将

设计填充到泛型中,使用约束和真实类和Wrapper< Tclass之间的共享接口,但结果仍然是

并不是你想要的。我认为如果泛型

支持声明的类型之间的协方差,你可以使用约束更容易地使它工作

。但它不是,所以你不能。


恕我直言,最简单的事情是只做重载版本的

方法,正如你在其他地方所做的那样。


如果你真的想要能够使用重载方法,我会说

解决方案是退后一步,重新思考整体设计。

由于设计现在存在,我不相信有什么方法可以为你做什么想要,因为两个班级之间没有任何明确的关系




现在,所有这些都说,我太迟了,而且我开始时,我几乎不是一个专家。\\ b
泛型。所以,也许其他人有更多鼓励给你的东西。 :)


Pete

It''s late, so maybe I''m not getting it. But here''s what I think I
understand:

The key here is that you don''t want to write two AddObject() methods,
one that takes the T, and one that takes the Wrapper<T>. You''d prefer
to have a single AddObject() method that can take either a T or a
Wrapper<T>.

Is that right?

If so, I believe the issue is that the compiler, at the line at which
the error occurs, has no way to know that T is related to E in the way
that you know it is.

I played around with constraints a little bit. Okay, a lot. Probably
more than I should have bothered with. :) There are ways to cram the
design into generics using constraints and a shared interface between
the real class and the Wrapper<Tclass, but the result really still
isn''t exactly what you''re looking for. I think that if generics
supported covariance between declared types, you could get it to work
more easily using constraints. But it doesn''t, so you can''t.

IMHO, the simplest thing is to just do overloaded versions of that
method, just as you''ve done elsewhere.

If you really really want to be able to use overloaded methods, I''d say
that the solution is to take a step back and rethink the overall design.
As the design exists right now, I''m not convinced there''s any way to
do what you want, because of the lack of any defined relationship
between the two classes.

Now, all that said, I _am_ up way too late, and I''m hardly an expert in
generics to start with. So, maybe someone else has something more
encouraging to offer you. :)

Pete


这篇关于通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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