You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Visual Studio 2022中搭配.NET Standard 2.0或.NET Framework 4.8使用CallerArgumentExpression特性

Can I use CallerArgumentExpressionAttribute in .NET Framework 4.8 or .NET Standard 2.0?

I'm familiar with using the CallerArgumentExpression attribute in Visual Studio 2022 with .NET 6.0 to capture the expression passed to a method, which helps generate friendlier error messages in diagnostic/test APIs and reduces code duplication. For example, I have this contract class for null checks:

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;
    }
}

And I use it like this:

using static ClassLibrary1.Contract;
static void test(string theString) {
    RequiresArgNotNull(theString); // No need to pass the parameter name explicitly
    Console.WriteLine(theString);
}

If theString is null, it throws an exception with a clear message:

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

I want to use this same functionality in .NET Framework 4.8 and/or .NET Standard 2.0. Is this possible?


Answer

Great question! The short answer is yes, you can use a version of this functionality in .NET Framework 4.8 and .NET Standard 2.0, but with a few key caveats since CallerArgumentExpressionAttribute is a native .NET 6+ runtime feature. Here's how to make it work smoothly:

1. Define your own copy of the attribute

Since the official attribute doesn't exist in older frameworks, you'll need to create an identical-looking version in your project. The C# compiler only cares about the attribute's name and signature, so this will trick it into generating the argument expression just like in .NET 6. Add this code to your project:

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

        public string ParameterName { get; }
    }
}

2. Ensure you're using a compatible compiler

This approach relies on C# 10 or later, which comes with Visual Studio 2022. Even though you're targeting .NET Framework 4.8/.NET Standard 2.0, the compiler version is what enables the expression injection. If you're stuck on an older Visual Studio version (pre-2022) that doesn't support C# 10, this won't work—you'll have to fall back to explicit nameof() calls for parameter names.

3. Adjust project settings if needed

Make sure your project is configured to use C# 10 or higher. In Visual Studio:

  • Right-click your project → Properties
  • Go to the Build tab → click Advanced
  • Set the Language version to C# 10 or Latest minor version

4. Handle cross-framework compatibility (if needed)

If your library targets multiple frameworks (including .NET 6+), use preprocessor directives to avoid conflicting with the official attribute:

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

        public string ParameterName { get; }
    }
}
#endif

What to expect

Once set up, you can use your Contract class exactly as you did in .NET 6. When you call RequiresArgNotNull(theString), the compiler will automatically inject "theString" as the expression parameter, and you'll get the same clear exception message when the argument is null. The only runtime difference is that we're using a custom attribute instead of the official one—but since the attribute is only used at compile time, this won't cause any runtime issues.


内容的提问来源于stack exchange,提问作者Matthew Watson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 02:57:48