C# 在集合中使用泛型类型,而在C中不使用泛型类#
在这种情况下,我有一个非泛型的类,但它需要在集合中存储泛型对象的实例。在下面的示例中,我无法将Foo设置为泛型,但我需要将请求对象存储在pendingRequests字典中。以下代码将在pendingRequests声明中给出一个错误,即“使用泛型类型请求需要'1'类型参数”,但如果我向请求中添加C# 在集合中使用泛型类型,而在C中不使用泛型类#,c#,generics,unity3d,C#,Generics,Unity3d,在这种情况下,我有一个非泛型的类,但它需要在集合中存储泛型对象的实例。在下面的示例中,我无法将Foo设置为泛型,但我需要将请求对象存储在pendingRequests字典中。以下代码将在pendingRequests声明中给出一个错误,即“使用泛型类型请求需要'1'类型参数”,但如果我向请求中添加,那么当我尝试在addRequest中添加到字典时,我会得到一个强制转换错误 我需要使字典声明通用,但不使Foo通用。这是可以做到的,还是我应该用另一种方式?还有一点需要补充,我一直使用.NET2.0,
,那么当我尝试在addRequest中添加到字典时,我会得到一个强制转换错误
我需要使字典声明通用,但不使Foo通用。这是可以做到的,还是我应该用另一种方式?还有一点需要补充,我一直使用.NET2.0,因为它需要与Unity3D一起使用
class Foo
{
private Dictionary<int, Request> pendingRequests;
void addRequest<T>(int sequence, Request<T> request) where T : Response
{
pendingRequests[sequence] = request;
}
}
class Request<T> where T : Response
{
}
class Response
{
}
class-Foo
{
私有字典挂起请求;
void addRequest(int序列,Request-Request),其中T:Response
{
pendingRequests[序列]=请求;
}
}
类请求,其中T:Response
{
}
班级反应
{
}
Foo不能是泛型的,因为除了保留泛型请求的集合外,它是完全独立于请求的。有一个Foo实例(称之为会话),但有几十种不同类型的请求。它不在乎请求是LoginRequest还是BuymerRequest。但是,该请求是泛型的,因为我使用提供的响应类型来构造当前类型的响应对象,并从通过线路传入的数据对其进行反序列化
那么您的集合也不应该是泛型的。您可能需要考虑放弃泛型定义并简单地使用继承。这应该会让你上路,虽然不是100%,但你的问题在用法上是模糊的。假设它使用LINQ(我认为是3.5+或更高),那么将它迁移到2.0应该是相当容易的
public class Foo
{
// initialize: best practice
private List<CacheRequest> _pendingRequests =
new List<CacheRequest>();
// upper case: best practice
public void AddRequest(int sequence, Request request)
{
if (request.Response == null)
{
throw new ArgumentException("Request Response cannot be null.");
}
_pendingRequests.Add(new CacheRequest()
{
Sequence = sequence,
Request = request,
ResponseType = request.Response.GetType()
});
}
public bool TryGetRequest<T>(int seq, out Request request, out T response)
where T : Request
{
response = null;
request = null;
var pendingRequest = _pendingRequests
.Where(cr => cr.ResponseType == typeof(T))
.FirstOrDefault(r => r.Sequence == seq);
var result = pendingRequest != null;
if (result)
{
request = pendingRequest.Request;
response = request.Response as T;
}
return result;
}
private class CacheRequest
{
public int Sequence { get; set; }
public Request Request { get; set; }
public Type ResponseType { get; set; }
}
}
public class Request
{
public Response Response { get; set; }
}
public abstract class Response { }
public class HttpResponse : Response { }
public class UdpResponse : Response { }
公共类Foo
{
//初始化:最佳做法
私有列表_pendingRequests=
新列表();
//大写:最佳实践
公共void AddRequest(整数序列,请求)
{
if(request.Response==null)
{
抛出新ArgumentException(“请求-响应不能为null”);
}
_pendingRequests.Add(新的CacheRequest()
{
顺序=顺序,
请求=请求,
ResponseType=request.Response.GetType()
});
}
公共bool TryGetRequest(int-seq,out-Request-Request,out-T-response)
其中T:请求
{
响应=空;
请求=null;
var pendingRequest=_pendingRequests
其中(cr=>cr.ResponseType==typeof(T))
.FirstOrDefault(r=>r.Sequence==seq);
var result=pendingRequest!=null;
如果(结果)
{
request=pendingRequest.request;
响应=请求。响应为T;
}
返回结果;
}
私有类缓存请求
{
公共整数序列{get;set;}
公共请求请求{get;set;}
公共类型响应类型{get;set;}
}
}
公共类请求
{
公共响应{get;set;}
}
公共抽象类响应{}
公共类HttpResponse:响应{}
公共类udpreponse:响应{}
例如:
var foo = new Foo();
foo.AddRequest(1, new Request() { Response = new HttpResponse() });
Request request;
HttpResponse httpResponse;
UdpResponse udpResponse;
if (foo.TryGetRequest<HttpResponse>(1, out request, out httpResponse))
{
Console.WriteLine("1 is an HttpResponse");
}
if (!foo.TryGetRequest<UdpResponse>(1, out request, out udpResponse))
{
Console.WriteLine("1 is not a UdpResponse");
}
var foo=new foo();
AddRequest(1,new Request(){Response=new HttpResponse()});
请求;
HttpResponse HttpResponse;
UdpResponse UdpResponse;
if(foo.TryGetRequest(1,out请求,out httpResponse))
{
WriteLine(“1是一个HttpResponse”);
}
if(!foo.TryGetRequest(1,out请求,out udpResponse))
{
Console.WriteLine(“1不是UDPRESSponse”);
}
输出:
1是一个HttpResponse
1不是UDPRESSONSE
我在回答另一个问题时发现了答案。我可以为非泛型的请求创建基类或接口。然后,通用请求从基本非通用请求继承。非泛型请求用于addRequest和Foo内部的集合。从我的Java角度来看,这是手动完成我习惯的类型擦除
class Foo
{
private Dictionary<int, IRequest> pendingRequests;
void addRequest(int sequence, IRequest request)
{
pendingRequests[sequence] = request;
}
}
class Request<T> : IRequest where T : Response
{
}
class Response
{
}
interface IRequest
{
}
class-Foo
{
私有字典挂起请求;
void addRequest(int序列,IRequest请求)
{
pendingRequests[序列]=请求;
}
}
类请求:IRequest,其中T:Response
{
}
班级反应
{
}
接口IRequest
{
}
能否创建一个非泛型的请求
类,该类以基为参数<代码>类请求:请求?您还没有解释为什么不能使用泛型…它不应该是字典
和添加请求(int-seq,Request-req)
?@ErikPhilips我不相信我可以将成员pendingRequests设置为泛型,而不将类Foo设置为泛型。@LeonardBrünings如果我使用Request,那么它将不允许我传入任何作为Request子对象的对象。。。例如LoginRequest。。。添加请求()。谢谢!我想我明白你的意思了。我相信我几分钟前找到的基类/接口解决方案更直接地得到了我想要的答案。请检查它,除非答案有问题,否则我打算接受这个答案,即使我自己写的。如果答案回答了您的问题,请绝对标记您的答案:)这很接近,但不提供100%类型安全性(在get上,您还没有提供方法,请查看我在get上100%类型安全性的答案)。请确保对请求进行空检查(如果使用接口或抽象基类)。@ErikPhilips它提供了类型安全性,因此在IRequest中定义的任何接口都必须完整,这正是我想要的:)基本上,我希望能够使用请求中定义的成员,而不依赖泛型,但是,由于我把它变成了泛型(出于其他内部目的),我在Foo中将它作为泛型处理。我的解决方案是将这些成员的定义移动到IRequest,然后使用它