[英]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.