C# 11 即将推出,因此我们将详细探讨其新功能。您可能会发现这些新功能非常好奇,即使它们并不多。今天,让我们仔细看看泛型数学支持、原始字符串文字、所需的修饰符、属性中的类型参数等。
C# 11 添加了对泛型属性的支持 — 现在我们可以像泛型类和方法一样声明它们。尽管我们之前已经能够在构造函数中将类型作为参数传递,但现在我们可以使用约束来指定应传递哪些类型。现在我们也不必一直使用运算符。where
typeof
这就是它在“装饰器”模式的简单实现示例中的工作方式。让我们定义泛型属性:
C#[AttributeUsage(AttributeTargets.Class)]
public class DecorateAttribute<T> : Attribute where T : class
{
public Type DecoratorType{ get; set; }
public DecorateAttribute()
{
DecoratorType = typeof(T);
}
}
接下来,我们实现一个层次结构(根据模式)和一个工厂来创建装饰对象。注意装饰属性:
C#public interface IWorker
{
public void Action();
}
public class LoggerDecorator : IWorker
{
private IWorker _worker;
public LoggerDecorator(IWorker worker)
{
_worker = worker;
}
public void Action()
{
Console.WriteLine("Log before");
_worker.Action();
Console.WriteLine("Log after");
}
}
[Decorate<LoggerDecorator>]
public class SimpleWorker : IWorker
{
public void Action()
{
Console.WriteLine("Working..");
}
}
public static class WorkerFactory
{
public static IWorker CreateWorker()
{
IWorker worker = new SimpleWorker();
if (typeof(SimpleWorker)
.GetCustomAttribute<DecorateAttribute<LoggerDecorator>>() != null)
{
worker = new LoggerDecorator(worker);
}
return worker;
}
}
让我们看看它是如何工作的:
C#var worker = WorkerFactory.CreateWorker();
worker.Action();
// Log before
// Working..
// Log after
请注意,限制尚未完全删除,应指定类型。例如,不能使用类的类型参数:
C#public class GenericAttribute<T> : Attribute { }
public class GenericClass<T>
{
[GenericAttribute<T>]
//Error CS8968 'T': an attribute type argument cannot use type parameters
public void Action()
{
You may ask, are GenericAttribute<int> and GenericAttribute<string> different attributes, or just multiple uses of the same one? Microsoft determined them to be the same attribute. This means, to use the attribute multiple times, you need to set the AllowMultiple property to true. Let's modify the above example:
C#public class DecorateAttribute<T> : Attribute where T : clas
Now the bject can be decorated several times:
C#[Decorate<TimerDecorator>]
public class SimpleWorker : IWorker
显然,这个新功能不是基本的,但库开发人员现在可以在属性中使用泛型时创建更加用户友好的界面。
在新版本的 C# 语言中,我们可以对泛型类型使用数学运算。
此新功能会导致两个常规后果:
现在我们得到了一个静态的抽象结构,可能看起来有点奇怪,但我不会说它完全没有意义。让我们检查一下此更新的实际结果。看看这个稍微做作的自然数实现示例(数字可以从字符串中相加和解析):
C#public interface IAddable<TLeft, TRight, TResult>where TLeft : IAddable<TLeft, TRight, TResult>
static abstract TResult operator +(TLeft left, TRight right);
public interface IParsable<T> where T : IParsable<T>
static abstract T Parse(string s);
public record Natural : IAddable<Natural, Natural, Natural>, IParsable<Natural>
public int Value { get; init; } = 0;
public static Natural Parse(string s) return new() { Value = int.Parse(s) };
public static Natural operator +(Natural left, Natural right)
return new() { Value = left.Value + right.Value };