繁体   English   中英

如何在 Visual Studio 2022 和 .net Standard 2.0 或 .net 4.8 中使用 CallerArgumentExpression?

[英]How can I use CallerArgumentExpression with Visual Studio 2022 and .net Standard 2.0 or .net 4.8?

在 Visual Studio 2022 和 .net 6.0 中,我们有新的CallerArgumentExpression属性,我们可以使用它来“捕获传递给方法的表达式,以在诊断/测试 API 中启用更好的错误消息并减少击键”

例如,我们可以编写一个 class 来检查 null 方法 arguments,如下所示:

public static class Contract
{
    public static T RequiresArgNotNull<T>(T? item, [CallerArgumentExpression("item")] string? expression = default, string? message = null)
        where T : class
    {
        if (item == null)
            throw new ArgumentNullException(
                expression ?? "<unknown>",
                message ?? (expression != null ? "Requires " + expression + " != null" : "RequiresArgNotNull() failed."));

        return item;
    }
}

可以这样使用:

using static ClassLibrary1.Contract; // To allow just putting RequiresArgNotNull()

...

static void test(string theString)
{
    RequiresArgNotNull(theString); // Note that we do NOT need to pass the parameter
                                   // name as a separate string.
    Console.WriteLine(theString);
}

如果theString是 null,则会抛出如下所示的异常:

System.ArgumentNullException: Requires theString != null
Parameter name: theString

我希望能够将此功能与 .net 4.8 和/或 .net 标准 2.0 一起使用。 这可能吗?

如果您使用的是 Visual Studio 2022,则可以通过定义CallerArgumentExpressionAttribute的本地internal实现,将CallerArgumentExpression与 .net 4.8 和/或 .net Standard 2.0 一起使用:

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
    internal sealed class CallerArgumentExpressionAttribute : Attribute
    {
        public CallerArgumentExpressionAttribute(string parameterName)
        {
            ParameterName = parameterName;
        }

        public string ParameterName { get; }
    }
}

请注意,您必须使用System.Runtime.CompilerServices命名空间才能使其正常工作。 通过使这个实现internal ,您可以保证它不会与任何系统定义的实现冲突。

这将编译为.net Standard 2.0目标,因此它也可以被以.net 4.8.net Core 3.1为目标的程序集使用。

另请注意,您仍然需要 Visual Studio 2022 及其 SDK 才能工作 - 如果您尝试使用 Visual Studio 2019,它将编译正常,但参数将为 null。

您可以在使用CallerArgumentExpression的程序集中包含上述 class ,它将按预期工作。


示例 .net 标准 2.0 class 库提供Contract.RequiresArgNotNull()

(为简洁起见,此示例程序集使用命名空间ClassLibrary1 。)

项目:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>8</LangVersion>
  </PropertyGroup>

</Project>

CallerArgumentExpression.cs:

namespace System.Runtime.CompilerServices
{
    #if !NET6_0_OR_GREATER

    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
    internal sealed class CallerArgumentExpressionAttribute : Attribute
    {
        public CallerArgumentExpressionAttribute(string parameterName)
        {
            ParameterName = parameterName;
        }

        public string ParameterName { get; }
    }

    #endif
}

合同.cs:

using System;
using System.Runtime.CompilerServices;

#nullable enable

namespace ClassLibrary1
{
    public static class Contract
    {
        public static T RequiresArgNotNull<T>(T? item, [CallerArgumentExpression("item")] string? expression = default, string? message = null)
            where T : class
        {
            if (item == null)
                throw new ArgumentNullException(
                    expression ?? "<unknown>",
                    message ?? (expression != null ? "Requires " + expression + " != null" : "RequiresArgNotNull() failed."));

            return item;
        }
    }
}

演示使用RequiresArgNotNull()的示例控制台应用程序:

using System;
using static ClassLibrary1.Contract;

#nullable enable

namespace Demo
{
    class Program
    {
        static void Main()
        {
            try
            {
                test(null!);
            }

            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());   
            }
        }

        static void test(string theString)
        {
            RequiresArgNotNull(theString);
            Console.WriteLine(theString);
        }
    }
}

这将 output 出现以下异常消息(对于我的特定构建):

System.ArgumentNullException: Requires theString != null
Parameter name: theString
   at ClassLibrary1.Contract.RequiresArgNotNull[T](T item, String expression, String message) in E:\Test\cs9\ConsoleApp1\ClassLibrary1\Contract.cs:line 18
   at Demo.Program.test(String theString) in E:\Test\cs9\ConsoleApp1\ConsoleApp1\Program.cs:line 25
   at Demo.Program.Main() in E:\Test\cs9\ConsoleApp1\ConsoleApp1\Program.cs:line 14

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM