繁体   English   中英

为什么 typeof(T).= instance?getType()?

[英]Why is typeof(T) != instance.getType()?

我正在开发一个工厂,它将根据类型返回接口的通用实现。

我的主要问题是由
在此处输入图像描述 为什么这些 typeof(TException).= exception?GetType() 分别是? 我必须更改什么才能获得正确的 TException 类型?

上面的代码导致 InvalidCast 异常,因为它尝试强制转换为IDocumedisExceptionHandler<DocumedisException>而不是IDocumedisExceptionHandler<FhirParsingException>

工厂实施:

internal class DocumedisExceptionHandlerFactory : IDocumedisExceptionHandlerFactory
{
    private readonly IDictionary<Type, object> _exceptionHandlers = new ConcurrentDictionary<Type, object>();

    public void RegisterExceptionHandler<TException>(IDocumedisExceptionHandler<TException> exceptionHandler)
        where TException : DocumedisException
    {
        _exceptionHandlers.Add(typeof(TException), exceptionHandler);
    }

    public IDocumedisExceptionHandler<TException> GetDocumedisExceptionHandler<TException>(TException exception)
        where TException : DocumedisException
    {
        _exceptionHandlers.TryGetValue(exception.GetType(), out var exceptionHandler);
        return (IDocumedisExceptionHandler<TException>) exceptionHandler;
    }
}

附带问题:有没有比使用object作为字典值更好的方法?

在启动时注册处理程序:

var exceptionHandlerFactory = app.ApplicationServices.GetService<IDocumedisExceptionHandlerFactory>();
exceptionHandlerFactory.RegisterExceptionHandler(new FhirParsingExceptionHandler());

FhirParsingExceptionHandler实现IDocumedisExceptionHandler

internal class FhirParsingExceptionHandler : IDocumedisExceptionHandler<FhirParsingException>
{
    public void HandleException(FhirParsingException exception, out HttpStatusCode httpStatusCode, out OperationOutcome.IssueType issueType, out string message)
    {
        httpStatusCode = HttpStatusCode.BadRequest;
        issueType = OperationOutcome.IssueType.Invalid;
        message = exception.Message;
    }
}

处理程序定义(其中TException是逆变的):

public interface IDocumedisExceptionHandler<in TException>
    where TException : DocumedisException
{
    void HandleException(TException exception, out HttpStatusCode httpStatusCode, out OperationOutcome.IssueType issueType, out string message);
}

FhirParsingException扩展DocumedisException

public class FhirParsingException : DocumedisException
{
   [...]
}

从中间件中检索处理程序:

public async Task Invoke(HttpContext context)
{
   try
   {
      await _next.Invoke(context);
   }
   catch (Exception ex)
   {
      if (ex is DocumedisException documedisException)
      {
         await HandleDocumedisExceptionAsync(context, documedisException);
      }
      else
      {
         throw;
      }
   }
}

private async Task HandleDocumedisExceptionAsync<TException>(HttpContext context, TException ex, MedicationAnalyzerErrorCode? errorCode = null)
   where TException : DocumedisException
{
   var exceptionHandler = _documedisExceptionHandlerFactory.GetDocumedisExceptionHandler(ex);
   [...]
}

typeof(TException)为您提供exception编译时类型。 exception.GetType()为您提供exception运行时类型。 这两者根本不需要相同,编译器唯一保证的是exception的运行时类型可以分配给TException变量。

考虑以下:

class Animal { }
class Turtle: Animal { }
bool CheckTypes<T>(T animal) where T: Animal 
{
     return typeof(T) == animal.GetType();
}

现在你有:

Animal animal = new Turtle();
Feed(animal);

Rest 放心, CheckTypes将返回false 泛型类型参数的类型是Animal但 Animal 的运行时类型Turtle animal

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM