泛型帮助 [英] Generics Help
问题描述
大家好,
我是C#和Generics的新手,我想知道是否有人给我一些
的建议。
我正在尝试使用泛型实现一个简单的DAO框架来保持我的代码尽可能干净,但是我得到了一个我觉得错误似乎是对我来说是正确的代码。我得到的错误是:
错误1无法隐式转换类型''Sample.PersonDao''到
''Sample.Dao< Sample .Model>''F:\Documents and Settings \ Bryan \ My
Documents\Visual Studio
2005 \Projects\EventManager\EventManager \\ \\ Sample.cs 22 24 EventManager
下面是一段代码片段,它将重现编译错误我
收到。
namespace示例
{
//所有Model对象的基类。
抽象类Model {}
//所有数据访问对象的基类。
抽象类Dao< TModelwhere TModel:模型{}
//人物模型。
类人物:模型{}
//人物模型的数据访问对象。
类PersonDao:Dao<人{}
//为模型返回DAO的工厂。
类DaoFactory
{
public Dao< ModelGetDao(模型型号)
{
if(model is Person)
{
//下一行的编译错误。
返回新的PersonDao();
}
>
返回null;
}
}
}
$ b $我在这里做错了吗?有什么我应该做的事吗?有没有可行的替代方法
更好?
提前谢谢,
布莱恩凯尔
Bryan Kyle写道:
大家好,
我是C#和Generics的新手,我想知道是否有人给我一些
的建议。
我'我正在尝试使用泛型实现一个简单的DAO框架来保持我的代码尽可能干净,但是我收到的错误似乎是对我来说是什么?
是正确的代码。我得到的错误是:
错误1无法隐式转换类型''Sample.PersonDao''到
''Sample.Dao< Sample .Model>''F:\Documents and Settings \ Bryan \ My
Documents\Visual Studio
2005 \Projects\EventManager\EventManager \\ \\ Sample.cs 22 24 EventManager
下面是一段代码片段,它将重现编译错误我
收到。
namespace示例
{
//所有Model对象的基类。
抽象类Model {}
//所有数据访问对象的基类。
抽象类Dao< TModelwhere TModel:模型{}
//人物模型。
类人物:模型{}
//人物模型的数据访问对象。
类PersonDao:Dao<人{}
//返回的工厂模型的DAO。
类DaoFactory
{
公共Dao< ModelGetDao(模型型号)
{
if(model is Person)
{
//下一行的编译错误。
返回新的PersonDao ();
}
返回null;
}
} < br $>
}
我在这里做错了吗?有什么我应该做的事吗?有没有可行的替代方法
更好?
提前致谢,
Bryan Kyle
你好Bryan,
不幸的是,这个版本的C#不支持
逆变/协方差,这就是你''尝试这样做。
例如,List< Ais不一样,并且不是List< Beven的子集如果
A继承自B.
-
希望这会有所帮助,
Tom Spink
谷歌首先,稍后再询问。
Tom Spink < ts **** @ gmail.com写信息
新闻:OK ************** @ TK2MSFTNGP02.phx.gbl ...
Bryan Kyle写道:
>大家好,
我是C#和Generics相当新,我想知道是否有人对我有一些建议。
我正在尝试使用泛型实现一个简单的DAO框架来保持/ >我的代码尽可能干净,但是我得到的错误似乎是对我来说是正确的代码。我得到的错误是:
错误1无法将类型''Sample.PersonDao'隐式转换为
''Sample.Dao< Sample.Model>''F:\\ \\文件和设置\ Bryan \我/
Documents\Visual Studio
2005 \Projects\EventManager \ EventManager \Sample。 cs 22 24
EventManager
下面是一段代码,它将重现我收到的编译错误。
名称空间示例
{< br //>所有Model对象的基类。
抽象类Model {}
//所有数据访问对象的基类。
抽象类Dao< TModelwhere TModel:模型{}
//人物模型。
类人物:模型{}
//人物模型的数据访问对象。
类PersonDao :Dao< Person {}
//返回模型DAO的工厂。
DaoFactory类
公共Dao< ModelGetDao(模型模型)
{
if(model is Person)
{
//下一行的编译错误。
返回新的PersonDao();
}
返回null;
}
}
}
我做错了什么ERE?我有什么应该做的吗?是否有其他方法可以更好地工作?
提前致谢,
Bryan Kyle
你好Bryan ,
不幸的是,这个版本的C#不支持
逆变/协方差,这就是你要做的事情。
例如,List< Ais不一样,并且不是List< Beven
的子集,如果
A继承自B.
实际上这会起作用,很难说服编译器确认它将会起作用。在下面的示例中,我进行了两处小改动。
首先,我在Dao< TModel>上引入了非泛型超类Dao。没有
这个Dao< TModelis是一个完全不相关的类型,每个都是它自己的继承层次结构的根。
Second我将方法GetDao声明为泛型方法,并引入了一个模糊(对象)转换来压缩编译器警告并更改了
类型的比较来自is。到==因为是包括子类,这个
不是你想要的:
public static Dao< TModelGetDao< TModel>()其中TModel:Model
{
if(typeof(TModel)== typeof(Person))
{
//下一行的编译错误。
返回(Dao< TModel>)(对象)新PersonDao();
}
完整示例:
namespace示例
{
//所有Model对象的基类。
抽象类Model {}
//所有数据访问对象的基类。
抽象类Dao {}
//基类系列。
抽象类Dao< TModel:Dao其中TModel:型号
{
}
//人模型。
类人物:模型{}
//人物模型的数据访问对象。
类PersonDao: Dao< Person>
{
}
//返回DAO的工厂一个模型。
类DaoFactory
{
public static Dao< TModelGetDao< TModel>()其中TModel:Model
{
if(typeof(TModel)== typeof(Person))
{
//下一行的编译错误。
返回(Dao< TModel>)(对象)新PersonDao();
}
返回null;
}
}
}
David
< blockquote>" Bryan Kyle" < br ******** @ gmail.comwrote:
我正在尝试使用泛型实现一个简单的DAO框架来保持
我的代码虽然尽可能干净,但是我收到的错误似乎是
给我正确的代码。
您遇到的事情称为泛型协方差,C#
不支持。基本上,列表< Pigeonis不是列表< Animal>。为什么?
好吧,如果确实如此,你就能做到这一点:
列表< Animalanimals =新列表< Pigeon>(鸽子);
animals.Add(新猫());
....这真的会把猫扔进鸽子之中,因为它<
会打破类型安全。
(你的例子中的模拟是Dao< Personis not a Dao< Model> ;.)
>
您的问题的解决方案有点复杂,我已经进入了
过去的这个新闻组的类似情况的详细解释 - 搜索对于generics covariance,大约2-6周前,你应该
找到它。
- Barry
-
http://barrkel.blogspot.com/
Hi All,
I''m fairly new to C# and Generics and I''m wondering if anyone has some
suggestions for me.
I''m trying to implement a simple DAO framework using generics to keep
my code as clean as I can, however I''m getting an error with what seems
to me to be correct code. The error I''m getting is:
Error 1 Cannot implicitly convert type ''Sample.PersonDao'' to
''Sample.Dao<Sample.Model>'' F:\Documents and Settings\Bryan\My
Documents\Visual Studio
2005\Projects\EventManager\EventManager\Sample.cs 22 24 EventManager
Below is a snippet of code that will reproduce compilation error I
receive.
namespace Sample
{
// Base class for all Model objects.
abstract class Model { }
// Base class for all Data Access Objects.
abstract class Dao<TModelwhere TModel : Model { }
// Person model.
class Person : Model { }
// Data Access Object for a Person model.
class PersonDao : Dao<Person{ }
// Factory that returns the DAO for a model.
class DaoFactory
{
public Dao<ModelGetDao(Model model)
{
if (model is Person)
{
// Compilation error on the next line.
return new PersonDao();
}
return null;
}
}
}
Am I doing something completely wrong here? Is there something I
should be doing? Is there an alternate approach that might work
better?
Thanks in advance,
Bryan Kyle
Bryan Kyle wrote:
Hi All,
I''m fairly new to C# and Generics and I''m wondering if anyone has some
suggestions for me.
I''m trying to implement a simple DAO framework using generics to keep
my code as clean as I can, however I''m getting an error with what seems
to me to be correct code. The error I''m getting is:
Error 1 Cannot implicitly convert type ''Sample.PersonDao'' to
''Sample.Dao<Sample.Model>'' F:\Documents and Settings\Bryan\My
Documents\Visual Studio
2005\Projects\EventManager\EventManager\Sample.cs 22 24 EventManager
Below is a snippet of code that will reproduce compilation error I
receive.
namespace Sample
{
// Base class for all Model objects.
abstract class Model { }
// Base class for all Data Access Objects.
abstract class Dao<TModelwhere TModel : Model { }
// Person model.
class Person : Model { }
// Data Access Object for a Person model.
class PersonDao : Dao<Person{ }
// Factory that returns the DAO for a model.
class DaoFactory
{
public Dao<ModelGetDao(Model model)
{
if (model is Person)
{
// Compilation error on the next line.
return new PersonDao();
}
return null;
}
}
}
Am I doing something completely wrong here? Is there something I
should be doing? Is there an alternate approach that might work
better?
Thanks in advance,
Bryan KyleHi Bryan,
Unfortunately, this version of C# does not support
contravariance/covariance, which is what you''re trying to do.
For example, List<Ais not the same, and is not a subset of List<Beven if
A inherits from B.
--
Hope this helps,
Tom Spink
Google first, ask later.
"Tom Spink" <ts****@gmail.comwrote in message
news:OK**************@TK2MSFTNGP02.phx.gbl...Bryan Kyle wrote:
>Hi All,
I''m fairly new to C# and Generics and I''m wondering if anyone has some
suggestions for me.
I''m trying to implement a simple DAO framework using generics to keep
my code as clean as I can, however I''m getting an error with what seems
to me to be correct code. The error I''m getting is:
Error 1 Cannot implicitly convert type ''Sample.PersonDao'' to
''Sample.Dao<Sample.Model>'' F:\Documents and Settings\Bryan\My
Documents\Visual Studio
2005\Projects\EventManager\EventManager\Sample. cs 22 24
EventManager
Below is a snippet of code that will reproduce compilation error I
receive.
namespace Sample
{
// Base class for all Model objects.
abstract class Model { }
// Base class for all Data Access Objects.
abstract class Dao<TModelwhere TModel : Model { }
// Person model.
class Person : Model { }
// Data Access Object for a Person model.
class PersonDao : Dao<Person{ }
// Factory that returns the DAO for a model.
class DaoFactory
{
public Dao<ModelGetDao(Model model)
{
if (model is Person)
{
// Compilation error on the next line.
return new PersonDao();
}
return null;
}
}
}
Am I doing something completely wrong here? Is there something I
should be doing? Is there an alternate approach that might work
better?
Thanks in advance,
Bryan Kyle
Hi Bryan,
Unfortunately, this version of C# does not support
contravariance/covariance, which is what you''re trying to do.
For example, List<Ais not the same, and is not a subset of List<Beven
if
A inherits from B.
Actually this will work, it''s just hard to convince the compiler that it
will work. In the sample below I made two small changes.
First I introduced a non-generic superclass Dao over Dao<TModel>. Without
this Dao<TModelis a family of completely unrelated types, each the root of
its own inheritence hierarchy.
Second I declared the method GetDao as a generic method, and introduced an
obfuscating (object) cast to supress the compiler warning and changed the
type comparison from "is" to "==" because "is" includes subclasses, and this
isn''t what you want:
public static Dao<TModelGetDao<TModel>() where TModel : Model
{
if (typeof(TModel) == typeof(Person))
{
// Compilation error on the next line.
return (Dao<TModel>)(object)new PersonDao();
}
Complete sample:
namespace Sample
{
// Base class for all Model objects.
abstract class Model { }
// Base class for all Data Access Objects.
abstract class Dao { }
// Family of base classes.
abstract class Dao<TModel: Dao where TModel : Model
{
}
// Person model.
class Person : Model { }
// Data Access Object for a Person model.
class PersonDao : Dao<Person>
{
}
// Factory that returns the DAO for a model.
class DaoFactory
{
public static Dao<TModelGetDao<TModel>() where TModel : Model
{
if (typeof(TModel) == typeof(Person))
{
// Compilation error on the next line.
return (Dao<TModel>)(object)new PersonDao();
}
return null;
}
}
}
David
"Bryan Kyle" <br********@gmail.comwrote:
I''m trying to implement a simple DAO framework using generics to keep
my code as clean as I can, however I''m getting an error with what seems
to me to be correct code.The thing you are running into is called generic covariance, which C#
doesn''t support. Basically, a List<Pigeonis not a List<Animal>. Why?
Well, if it were true, you''d be able to do this:
List<Animalanimals = new List<Pigeon>(pigeons);
animals.Add(new Cat());
.... and that would really throw the cat amongst the pigeons, since it
would break type safety.
(The analogue in your example is that Dao<Personis not a Dao<Model>.)
The solution to your problem is somewhat complex, and I''ve gone into
detailed explanations of similar situations on this newsgroup in the
past - search for generics covariance, about 2-6 weeks ago, you should
find it.
-- Barry
--
http://barrkel.blogspot.com/
这篇关于泛型帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!