C# 接口<;T>;:T
假设我有这样的类和接口结构:C# 接口<;T>;:T,c#,.net,generics,inheritance,interface,C#,.net,Generics,Inheritance,Interface,假设我有这样的类和接口结构: interface IService {} interface IEmailService : IService { Task SendAsync(IMessage message); } class EmailService : IEmailService { async Task SendAsync(IMessage message) { await ... } } interface ICircuitBrea
interface IService {}
interface IEmailService : IService
{
Task SendAsync(IMessage message);
}
class EmailService : IEmailService
{
async Task SendAsync(IMessage message)
{
await ...
}
}
interface ICircuitBreaker<TService> : IService where TService : IService
{
TService Service { get; set; }
Task<IResult> PerformAsync(Func<Task<Iresult>> func);
}
class EmailServiceCircuitBreaker : ICircuitBreaker<IEmailService>
{
IEmailService Service { get; set; }
public EmailServiceCircuitBreaker(IEmailService service)
{
Service = service;
}
public async Task<IResult> PerformAsync(Func<Task<Iresult>> func)
{
try
{
func();
}
catch(Exception e){//Handle failure}
}
}
因此,我可以包装IEmailService
中的每个方法,Send(…)
将如下所示:
async Task<IResult> IEmailService.SendAsync(IMessage m)
=> await PerformAsync(async () => await Service.SendAsync(m));
异步任务IEmailService.SendAsync(IMessage m)
=>wait-PerformAsync(async()=>wait-Service.sendaync(m));
在控制器中,我可以将其用作IEmailService
,即使这是icirciitbreaker
,我也不知道
但是,如果我的任何同事将实现
ICircitBreaker
,我想强制他的类在不需要新的语言约束时也实现T
,那么在编译时可以抛出自定义错误
您可以使用DiagnosticAnalyzer
使用DiagnosticanAnalyzer
,您可以搜索模式并引发异常
context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
{
var node = (ObjectCreationExpressionSyntax)context.Node;
if (node != null && node.Type != null && node.Type is IdentifierNameSyntax)
{
var type = (IdentifierNameSyntax)node.Type;
var symbol = (INamedTypeSymbol)context.SemanticModel.GetSymbolInfo(type).Symbol;
var isIService = IsInheritedFromIService(symbol);
if (isIService )
{
... //Check you logic
context.ReportDiagnostic(diagnostic);
}
}
}
private static bool IsInheritedFromIService(ITypeSymbol symbol)
{
bool isIService = false;
var lastParent = symbol;
if (lastParent != null)
{
while (lastParent.BaseType != null)
{
if (lastParent.BaseType.Name == "IService")
{
isIService = true;
lastParent = lastParent.BaseType;
break;
}
else
{
lastParent = lastParent.BaseType;
}
}
}
return isIService ;
}
描述似乎有点倒退,但您是否试图描述一个类似于Eric Lippert中描述的场景?问题到底是什么?部件
接口接口:IService,其中IService:T
在语法上不正确;类型约束必须在类型参数上。据我所知,C#不支持这种约束,如果您不希望所有团队成员都遵守严格的规则,您可以使用Roslyn的功能Compiler@Codor是的,我知道incorrect@VibeeshanRC你能提供一些关于这个主题的链接吗?
context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
{
var node = (ObjectCreationExpressionSyntax)context.Node;
if (node != null && node.Type != null && node.Type is IdentifierNameSyntax)
{
var type = (IdentifierNameSyntax)node.Type;
var symbol = (INamedTypeSymbol)context.SemanticModel.GetSymbolInfo(type).Symbol;
var isIService = IsInheritedFromIService(symbol);
if (isIService )
{
... //Check you logic
context.ReportDiagnostic(diagnostic);
}
}
}
private static bool IsInheritedFromIService(ITypeSymbol symbol)
{
bool isIService = false;
var lastParent = symbol;
if (lastParent != null)
{
while (lastParent.BaseType != null)
{
if (lastParent.BaseType.Name == "IService")
{
isIService = true;
lastParent = lastParent.BaseType;
break;
}
else
{
lastParent = lastParent.BaseType;
}
}
}
return isIService ;
}