多目标项目(含net472)使用C#11 required特性编译报错的解决方法
环境:Visual Studio 2022 v17.4.0,已安装.NET 7 SDK。
我有一个多目标项目,目标框架为net7.0;net472,项目配置如下:
<PropertyGroup> <OutputType>Exe</OutputType> <TargetFrameworks>net7.0;net472</TargetFrameworks> <LangVersion>11.0</LangVersion> <!--其他配置--> </PropertyGroup>
尝试使用C# 11的新特性required,代码如下:
public class Person { public required int Id { get; set; } }
针对net472目标编译时出现以下错误:
Error CS0656 Missing compiler required member 'System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute..ctor'
Error CS0656 Missing compiler required member 'System.Runtime.CompilerServices.RequiredMemberAttribute..ctor'
目前我的临时解决方法是使用条件编译:
public class Person { public #if NET7_0 required #endif int Id { get; set; } }
请问如何在包含net47x的多目标项目中支持C# 11的required新特性?
错误的核心原因是:.NET Framework 4.7.x的类库中并不包含System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute和RequiredMemberAttribute这两个特性类,而C# 11的required语法依赖这些属性完成编译检查,因此针对旧框架目标编译时会报错。
要在多目标项目中统一使用required特性,无需给属性加条件编译,可以通过以下方式解决:
- 手动添加缺失的特性类定义
在项目中新建一个代码文件(比如RequiredAttributes.cs),使用条件编译仅针对非.NET 7及以上的框架目标定义这些缺失的特性:
#if !NET7_0_OR_GREATER namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)] public sealed class CompilerFeatureRequiredAttribute : Attribute { public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } public string FeatureName { get; } public bool IsOptional { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public sealed class RequiredMemberAttribute : Attribute { } // 同时需要定义IsExternalInit,用于支持init setter(如果项目中用到的话) public static class IsExternalInit { } } #endif
添加这个文件后,编译器在处理net472目标时会找到这些特性类的定义,就能正常编译使用required特性的代码了。
需要注意的是:这些特性的定义只需要满足编译器的基本结构要求即可,不需要实现完整的框架级功能——因为编译器仅依赖这些特性的存在来识别required语法,而旧框架运行时并不需要这些特性的实际逻辑。
内容的提问来源于stack exchange,提问作者M.Hassan

