Novidades do C# 8.0: Default interface methods
Olá, neste artigo eu vou escrever sobre a novidade do C# 8 default interface methods. Neste artigo você poderá ver um resumo das novidades que eu acho mais relevantes que vieram no C# 8.
Antes do C# 8
public interface ILimit
{
IFilterBuilder Limit(in uint limit);
}
public interface ISkip
{
IFilterBuilder Skip(in uint skip);
}
public interface ISelect
{
IFilterBuilder Select(params string[] fields);
}
public interface IFilterBuilder : ILimit, ISkip, ISelect
{
string Build();
}
public sealed class FilterBuilder : IFilterBuilder
{
private readonly ICollection<string> filters;
private FilterBuilder() => this.filters = new List<string>();
public IFilterBuilder Skip(in uint skip)
{
var newSkip = skip < 1
? 1
: skip;
this.filters.Add($"filter[skip]={newSkip}");
return this;
}
public IFilterBuilder Limit(in uint limit)
{
var newLimit = limit < 1
? 1
: limit;
this.filters.Add($"filter[limit]={newLimit}");
return this;
}
public IFilterBuilder Select(params string[] fields)
{
foreach (var field in fields)
{
this.filters.Add($"filter[fields][{field}]=true");
}
return this;
}
public string Build() => string.Join("&", this.filters);
public static IFilterBuilder NewFilterBuilder() => new FilterBuilder();
}Antes do C# 8 (uma opção com interface extensions)
Este exemplo foi inspirado no artigo Pseudo Traits in C#, que traz uma abordagem de como podemos fazer praticamente a mesma coisa sem precisar desta nova funcionalidade.
public interface IFilterBase
{
IFilterBuilder AddFilters(params string[] values);
}
public interface ILimit : IFilterBase
{
}
public static partial class FilterExtension
{
public static IFilterBuilder Limit(this ILimit @this, uint limit)
{
var newLimit = limit < 1
? 1
: limit;
return @this
.AddFilters($"filter[limit]={newLimit}");
}
}
public interface ISkip : IFilterBase
{
}
public static partial class FilterExtension
{
public static IFilterBuilder Skip(this ISkip @this, uint skip)
{
var newSkip = skip < 1
? 1
: skip;
return @this
.AddFilters($"filter[skip]={newSkip}");
}
}
public interface ISelect : IFilterBase
{
}
public static partial class FilterExtension
{
public static IFilterBuilder Select(this ISelect @this, params string[] fields) => @this
.AddFilters(fields
.Select(field => $"filter[fields][{field}]=true")
.ToArray());
}
public interface IFilterBuilder : ILimit, ISkip, ISelect
{
string Build();
}
public sealed class FilterBuilder : IFilterBuilder
{
private readonly ICollection<string> filters;
private FilterBuilder() => this.filters = new List<string>();
public string Build() => string.Join("&", this.filters);
public IFilterBuilder AddFilters(params string[] values)
{
foreach (var value in values)
{
this.filters.Add(value);
}
return this;
}
public static IFilterBuilder NewFilterBuilder() => new FilterBuilder();
}Depois do C# 8
public interface IFilterBase
{
IFilterBuilder AddFilters(params string[] values);
}
public interface ISkip : IFilterBase
{
IFilterBuilder Skip(in uint skip)
{
var newSkip = skip < 1
? 1
: skip;
return this
.AddFilters($"filter[skip]={newSkip}");
}
}
public interface ILimit : IFilterBase
{
IFilterBuilder Limit(in uint limit)
{
var newLimit = limit < 1
? 1
: limit;
return this
.AddFilters($"filter[limit]={newLimit}");
}
}
public interface ISelect : IFilterBase
{
public IFilterBuilder Select(params string[] fields) => this
.AddFilters(fields
.Select(field => $"filter[fields][{field}]=true")
.ToArray());
}
public interface IFilterBuilder : ILimit, ISkip, ISelect
{
string Build();
}
public sealed class FilterBuilder : IFilterBuilder
{
private readonly ICollection<string> filters;
private FilterBuilder() => this.filters = new List<string>();
public string Build() => string.Join("&", this.filters);
public IFilterBuilder AddFilters(params string[] values)
{
foreach (var value in values)
{
this.filters.Add(value);
}
return this;
}
public static IFilterBuilder NewFilterBuilder() => new FilterBuilder();
}Considerações finais
Esta nova funcionalidade dividiu um pouco a opinião da comunidade, alguns gostaram e outros nem tanto, abaixo dois artigos que ilustram bem essas opiniões:
O último exemplo com a implementação desta nova funcionalidade foi retirado do projeto Http.Query.Filter.
Obrigado pela visita 🙂!
Comentários