C# 在集合中使用泛型类型,而在C中不使用泛型类#

C# 在集合中使用泛型类型,而在C中不使用泛型类#,c#,generics,unity3d,C#,Generics,Unity3d,在这种情况下,我有一个非泛型的类,但它需要在集合中存储泛型对象的实例。在下面的示例中,我无法将Foo设置为泛型,但我需要将请求对象存储在pendingRequests字典中。以下代码将在pendingRequests声明中给出一个错误,即“使用泛型类型请求需要'1'类型参数”,但如果我向请求中添加,那么当我尝试在addRequest中添加到字典时,我会得到一个强制转换错误 我需要使字典声明通用,但不使Foo通用。这是可以做到的,还是我应该用另一种方式?还有一点需要补充,我一直使用.NET2.0,

在这种情况下,我有一个非泛型的类,但它需要在集合中存储泛型对象的实例。在下面的示例中,我无法将Foo设置为泛型,但我需要将请求对象存储在pendingRequests字典中。以下代码将在pendingRequests声明中给出一个错误,即“使用泛型类型请求需要'1'类型参数”,但如果我向请求中添加
,那么当我尝试在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,然后使用它