is there a way to only allow certain values as parameters in a method. Not at runtime, I mean it already shows an error when coding. For example:
I have this method:
public bool addPoints(Guid userId, uint amount)
{
...
}
It will be called multiple times in the code. But, I only want people to pass certain values. Those values are defined somewhere e.q. a class:
public class LeaderboardPoints
{
public const uint CREATE = 30;
public const uint REPLICATE = 15;
public const uint REMIX = 15;
public const uint COMMENT = 15;
}
Is there a way, that I can force the argument to be one of those props? or is there maybe another way to make sure that the right amount is passed?
Thanks!!
CodePudding user response:
An enum
is one option, but enums are just named integers - you can get them wrong and pass any integer (it is just more awkward).
Another way to make it much harder to pass in something wrong is to encapsulate the values in a type, using a non-public constructor to make it impossible (without reflection at least) to create invalid options. For example:
public bool AddPoints(Guid userId, Points points)
{
// something = points.Value
}
//...
public readonly struct Points
{
public uint Value {get;}
private Points(uint value) => Value = value;
public static Points Create {get;} = new Points(30);
public static Points Replicate {get;} = new Points(15);
public static Points Remix {get;} = new Points(15);
public static Points Comment {get;} = new Points(15);
}
// ...
something.AddPoints(userId, Points.Create);
You could also optionally give things names, if it helps debugging.
CodePudding user response:
As others have commented, you can define and use an enum
type for this:
public enum LeaderBoardAction : uint
{
CREATE = 30,
REPLICATE = 15,
REMIX = 15,
COMMENT = 15
}
Then use Enum.IsDefined()
to ensure no one passes arbitrary values in place of a defined enum label:
public bool AddPoints(Guid userId, LeaderBoardAction action)
{
if(!Enum.IsDefined(typeof(LeaderBoardAction), action))
throw new ArgumentException("Expected a valid leader board action", nameof(action));
// ...
}
CodePudding user response:
or is there maybe another way to make sure that the right amount is passed?
Another approach is to take away the parameter and instead give named methods that they can call; you have just 4 options so it's certainly feasible to:
private bool AddPoints(Guid userId, uint amount)
{
...
}
public bool AddCreatePoints(Guid userId) => AddPoints(userId, LeaderboardPoints.CREATE);
public bool AddReplicatePoints(Guid userId) => AddPoints(userId, LeaderboardPoints.REPLICATE);
public bool AddRemixPoints(Guid userId) => AddPoints(userId, LeaderboardPoints.REMIX);
public bool AddCommentPoints(Guid userId) => AddPoints(userId, LeaderboardPoints.COMMENT);
As with any such things there's always that drag of how much you need to change when adding more options; for my money I would just use an enum and trust developers not to put crazy values in