简体   繁体   中英

How to create a constructor which accepts up to 4 arguments?

I'm creating an attribute which accepts up to 4 arguments.

I've coded this way:

internal class BaseAnnotations
{

    public const string GET = "GET";
    public const string POST = "POST";
    public const string PATCH = "PATCH";
    public const string DELETE = "DELETE";


    public class OnlyAttribute : Attribute
    {
        public bool _GET = false;
        public bool _POST = false;
        public bool _PATCH = false;
        public bool _DELETE = false;

        public OnlyAttribute(string arg1)
        {
            SetMethod(arg1);
        }

        public OnlyAttribute(string arg1, string arg2)
        {
            SetMethod(arg1);
            SetMethod(arg2);
        }

        public OnlyAttribute(string arg1, string arg2, string arg3)
        {
            SetMethod(arg1);
            SetMethod(arg2);
            SetMethod(arg3);
        }

        public OnlyAttribute(string arg1, string arg2, string arg3, string arg4)
        {
            SetMethod(arg1);
            SetMethod(arg2);
            SetMethod(arg3);
            SetMethod(arg4);
        }

        public void SetMethod(string arg)
        {
            switch (arg)
            {
                case GET: _GET = true; break;
                case POST: _POST = true; break;
                case PATCH: _PATCH = true; break;
                case DELETE: _DELETE = true; break;
            }
        }
    }
}

I need to use it like this:

public class ExampleModel : BaseAnnotations
{
    /// <summary>
    /// Example's Identification 
    /// </summary>
    [Only(GET, DELETE)]
    public long? IdExample { get; set; }

    // ...

Is there any way to code in only one constructor the 4 constructors above to avoid repetition?

I'm thinking in something like JavaScript's spread operator (...args) => args.forEach(arg => setMethod(arg)) .

Thanks in advance.

I'm going to suggest rethinking your design here. Consider:

[Flags]
public enum AllowedVerbs
{
    None = 0,
    Get = 1,
    Post = 2,
    Patch = 4,
    Delete = 8
}
public class OnlyAttribute : Attribute
{
    private readonly AllowedVerbs _verbs;
    public bool Get => (_verbs & AllowedVerbs.Get) != 0;
    public bool Post => (_verbs & AllowedVerbs.Post) != 0;
    public bool Patch => (_verbs & AllowedVerbs.Patch) != 0;
    public bool Delete => (_verbs & AllowedVerbs.Delete ) != 0;
    public OnlyAttribute(AllowedVerbs verbs) => _verbs = verbs;
}

Then callers can use:

[Only(AllowedVerbs.Get)]

or

[Only(AllowedVerbs.Post | AllowedVerbs.Delete)]

Good answers, though consider going with 4 attributes instead. For your example, this might work.

public class GetAttribute: Attribute {}
public class PostAttribute: Attribute {}
public class PatchAttribute: Attribute {}
public class DeleteAttribute: Attribute {}

[GET] [DELETE]
public long? IdExample { get; set; }

It's simple and direct. Sure there are more attributes, but you're likely to have many more instances where you need them.

Each attribute would have a default constructor. The mere existence of the attribute for each operation would be enough to convey what is allowed.

You can try this

public OnlyAttribute(params string[] parameters)
{
    foreach(var p in parameters) SetMethod(p);
}
 public OnlyAttribute(params string[] parameters)
 {
        if (parameters.Length > 4) throw new ArugumentException(nameof(parameters));

        foreach (var param in parameters)
        {
            SetMethod(param);
        }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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