簡體   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