C# 为什么是typeof(T)!=实例。getType()?
我正在一家工厂工作,它将根据类型返回接口的通用实现 我的主要问题由C# 为什么是typeof(T)!=实例。getType()?,c#,generics,casting,C#,Generics,Casting,我正在一家工厂工作,它将根据类型返回接口的通用实现 我的主要问题由 为什么这些类型的(TException)!=异常。GetType()?分别而言,我需要更改什么才能获得正确的TException类型 上述代码导致InvalidCast异常,因为它尝试强制转换到IDocumedisExceptionHandler而不是IDocumedisExceptionHandler internal class FhirParsingExceptionHandler : IDocumedisExceptio
为什么这些类型的(TException)!=异常。GetType()?分别而言,我需要更改什么才能获得正确的TException类型 上述代码导致InvalidCast异常,因为它尝试强制转换到
IDocumedisExceptionHandler
而不是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;
}
}
工厂实施:
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;
}
}
其中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;
}
}
和FhirParsingException
扩展documediseException
:
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);
[...]
}
公共异步任务调用(HttpContext上下文)
{
尝试
{
wait_next.Invoke(上下文);
}
捕获(例外情况除外)
{
如果(例如是documediseption documediseption)
{
等待处理ocumedisexceptionsync(上下文,documedisException);
}
其他的
{
投掷;
}
}
}
私有异步任务HandleDocuMediaSexceptionAsync(HttpContext上下文,TException ex,MedicalationAnalyzerErrorCode?errorCode=null)
其中TException:documediseption
{
var exceptionHandler=\u documedisExceptionHandlerFactory.GetDocumedisExceptionHandler(ex);
[...]
}
typeof(TException)
提供了异常的编译时类型exception.GetType()
提供运行时类型exception
。这两者不必完全相同,编译器所做的唯一保证是exception
的运行时类型将可分配给TException
变量
考虑以下几点:
class Animal { }
class Turtle: Animal { }
bool CheckTypes<T>(T animal) where T: Animal
{
return typeof(T) == animal.GetType();
}
请放心,CheckTypes
将返回false
;泛型类型参数的类型是Animal
,但Animal
的运行时类型实际上是Turtle
这是否回答了您的问题@帕夫拉尼霍斯基不是真的。它解释了差异,但不是我如何获得正确类型的TException。正如InBetween所解释的,它是在编译时确定的。IDocumedisExceptionHandler
是如何声明的?是否与TException
相关?看来,你的问题与泛型有关mostly@PavelAnikhouski它是相反的(只是因为resharper让我这么做)。我已经编辑了这个问题,以包括界面。如果你投的是无效的,它将在协变通用界面的情况下工作。你们应该花一些时间来完善你们当前的方法,并编写代码。这回答了为什么的主要问题,谢谢!但是,我没有找到一种方法来解决我的问题,即从工厂中检索类型化的处理程序,它需要一个确切的异常类型。我可以传递DocumedisException并将其强制转换到处理程序中,但我确实希望避免这种情况,@Philipple显示IDocumedisExceptionHandler
界面。如果可以使其协变(IDocumedisExceptionHandler
),则转换应该成功;与IEnumerable
相同,可以强制转换为IEnumerable
。如果它是反变的或不变的,那么您将陷入当前设置。我已经按照Pavel的要求添加了接口定义。我将不得不读一些关于协变和逆变的内容。@Philippe接口是逆变的,因此您尝试的演员阵容无效。在我可以支配的时间内,我想不出一种方法使其协变。我将documedesception传递给处理程序,使其成为非泛型。如果需要,处理程序可以将其强制转换。不完美,但功能齐全。
class Animal { }
class Turtle: Animal { }
bool CheckTypes<T>(T animal) where T: Animal
{
return typeof(T) == animal.GetType();
}
Animal animal = new Turtle();
Feed(animal);