7

I was told that in c# attributes are not allowed on the auto-implemented properties. Is that true? if so why?

EDIT: I got this information from a popular book on LINQ and could not believe it! EDIT: Refer page 34 of LINQ Unleashed by Paul Kimmel where he says "Attributes are not allowed on auto-implemented properties, so roll your own if you need an attribute"

Tad Donaghe
  • 6,625
  • 1
  • 29
  • 64
suhair
  • 10,895
  • 11
  • 52
  • 63
  • Could you say *exactly* what the information is? (I think it would be fair to give the name and reference for the book, btw.) – Jon Skeet Jan 21 '09 at 11:32
  • Get used to believing it - in text and in tools. We all make mistakes. I remember back in the day the Turbo C++ 1.0 compiler had an internal memory leak on copy constructor (or something related to that). I couldn't believe it was the compiler's fault and not a mistake in source code until I proved it. They fixed it in the next version. – John K Dec 10 '09 at 23:46

5 Answers5

12

You can apply attributes to automatic properties without a problem.

Quote from MSDN:

Attributes are permitted on auto-implemented properties but obviously not on the backing fields since those are not accessible from your source code. If you must use an attribute on the backing field of a property, just create a regular property.

aku
  • 122,288
  • 32
  • 173
  • 203
9

The easiest way to prove that's wrong is to just test it:

using System;
using System.ComponentModel;
using System.Reflection;

class Test
{
    [Description("Auto-implemented property")]
    public static string Foo { get; set; }  

    static void Main(string[] args)
    {
        var property = typeof(Test).GetProperty("Foo");
        var attributes = property.GetCustomAttributes
                (typeof(DescriptionAttribute), false);

        foreach (DescriptionAttribute description in attributes)
        {
            Console.WriteLine(description.Description);
        }
    }
}

I suggest you email the author so he can publish it as an erratum. If he meant that you can't apply an attribute to the field, this will give him a chance to explain more carefully.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

I think that author meant, that you can't apply custom attributes to private backing field. For example, if you want to mark automatic property as non serialized, you can't do this:

[Serializable]
public class MyClass
{
    [field:NonSerializedAttribute()]
    public int Id
    {
        get;
        private set;
    }
}

This code compiles, but it doesn’t work. You can apply attribute to property itself, but you can't apply it for backing field.

Sergey Teplyakov
  • 11,477
  • 34
  • 49
1

Note also that any Automatic property will have the CompilerGeneratedAttribute applied to it as well.

ShuggyCoUk
  • 36,004
  • 6
  • 77
  • 101
0

The current version of Visual Studio and C# compilers support this. I tested with VS 16.4.2 with C# 8.0 enabled. I don't know exactly which version it was enabled in but it's good news.

Syntax:

[field: NonSerialized]
public SomeNonSerializableType MyAutoProperty { get; set; } = DefaultValueAfterSerialization;

Practical use case; support neat/round-trip-able qualified XML serialization without messy backing fields but avoid runtime exceptions and resolve code analysis error CA2235:

/// <summary>
/// XML name table for serialization.
/// </summary
[XmlSerializerNamespaces]
[field: NonSerialized]
public XmlSerializerNamespaces XmlNamespaces { get; set; } = new XmlSerializerNamespaces();

If you're working on one of the new "SDK" style projects with .NET Core 3, .NET Standard 2.1 or later it will work immediately as they default to language version 8. Otherwise for all "legacy" .NET Framework and non-SDK projects you'll have to add the "LangVersion" setting to your project as documented here to "8.0" or "latest".

Tony Wall
  • 1,382
  • 20
  • 18