泛型帮助 [英] Generics Help

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

问题描述

大家好,


我是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 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.

--
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屋!

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