13

I saw this answer from this link Adding parameters to custom attributes of how is to add parameters on Custom Attribute

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(params int[] values) {
       this.Values = values;
    }
}

[MyCustomAttribute(3, 4, 5)]
class MyClass { }

Now I am wondering if can't it be write like this?

class MyCustomAttribute : Attribute {
    private int[] _values;

    public MyCustomAttribute(params int[] values) {
       _values = values;
    }
}

[MyCustomAttribute(3, 4, 5)]
class MyClass { }

I changed the property Values into a variable _values. I also made it private and it works fine when I tried it.

Can someone enlighten me why the accepted answer is valid?

Community
  • 1
  • 1
  • "Can someone enlighten me why the accepted answer is valid?" -- You haven't posted anything to suggest that it's invalid. At best you've shown that there's more than one way that works. So why do you think there's anything wrong with the answer you've read? –  Oct 15 '16 at 15:49
  • Ask yourself what you can do with your custom attribute. Hint: the main purpose of the attributes is not to be jus instantiated. – Ivan Stoev Oct 15 '16 at 15:51

3 Answers3

15

The accepted answer uses the public property instead of a private field. The benefit of public property is you can omit the constructor and supply the values of the properties in the default constructor.

I change your first code, the one with public property, to something like this.

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }
}

[MyCustomAttribute(Values = new int[] { 3, 4, 5 })]
class MyClass { }
Han
  • 3,052
  • 2
  • 22
  • 31
  • how to pass this 3,4,5 value from model or controller or from that view? I mean is there any way to pass the value from outside of the class "MyClass"? – Md Aslam Apr 07 '20 at 11:52
  • @Md Aslam - from what I understand it's not possible to do it in attributes – Mariusz Jun 24 '21 at 11:53
5

For [MyCustomAttribute(3, 4, 5)] the parameter list is unnamed, so the the constructor of MyCustomAttribute is used.

Therefore it does not matter, if there is a public Values properties.

In your first code sample it is acceptable to use [MyCustomAttribute(3, 4, 5)] and [MyCustom(Values = new[] {3, 4, 5})].

The second code sample "only" accepts [MyCustomAttribute(3, 4, 5)].

Ralf Bönning
  • 14,515
  • 5
  • 49
  • 67
  • did you mean that "my code or the second code" is also correct and acceptable? –  Oct 15 '16 at 15:41
  • Both of your codes are acceptable. See the MSDN sample in this [link](https://msdn.microsoft.com/en-us/library/84c42s56(v=vs.110).aspx). It's similar to your second code. Also see my answer for a variant of your first code. – Han Oct 15 '16 at 15:44
  • @RenanteAbril - I have added the point, that both samples are correct. The only difference is how the integer array is provided (via constructor or via property setter). – Ralf Bönning Oct 15 '16 at 15:56
5

There are differences, and it is all about reflection.

Main among them is the fluency that we get - we could either use the constructor or the Values property.

enter image description here

public class MyCustomAttribute : Attribute
{
    public int[] Values { get; set; } = new int[] { 1, 2, 3 };

    public MyCustomAttribute(params int[] values)
    {
        this.Values = values;
    }
}

[MyCustom(1, 2, 3)]
class MyClass
{

}

[MyCustom(Values = new int[] { 1, 2, 3})]
public class MyAnotherClass
{
}

Another factor is reflection to get the property; With the Values field being public, we could use the below to get the details but not with private:

var data = typeof(MyCustomAttribute).GetProperty("Values");
L J
  • 5,249
  • 3
  • 19
  • 29