C# User Input Validation - c#

how can I validate user input in my method with my interface, where all allowed inputs are stored?
if I do so then I get System.NullReferenceException:
public interface INumbUnit
{
public string UnitName { get; set; }
}
public void ValidateNumb()
{
INumbUnit? x = null;
while (string.IsNullOrEmpty(UserSourceUnit))
{
Console.WriteLine("[ERROR] Input can't be empty! Please try again.");
ChooseUnits();
}
while(UserSourceUnit != x.UnitName) //0Reference
{
Console.WriteLine("[ERROR] No such unit for selection! Please try again.");
}
}
UserSourceUnit is just a Console.ReadLine
UnitNames are stored in extern classes but there is still a reference to them, so I don't think that's the problem

I suspect you are new to programming, so you have to imagine that both INumbUnit and UnitName can be null.
So either you want to do a check for INumbUnit beeing null, or you want to make sure it is never null.
And you need to understand that this line
INumbUnit? x = null;
most likely need to be replaced with a real object, like
INumbUnit? x = new NumbUnit();
And then you do another class
public class NumbUnit:INumbUnit

Related

C# Working with objects (properly a byRef Byval problem)

I have my Compressors class:
public class Compressors
{
public Refrigerant Output { get; set; }
public Refrigerant Input { get; set; }
// Constructor
public Compressors(Refrigerant input)
{
Input = input;
}
}
In my main code I have:
var Compressor1 = new Compressors(BeforeComp);
var Compressor2 = new Compressors(Compressor1.Output);
Looking at is fine
Compressor1.Input
Compressor1.Output
But looking at
Compressor2.Input //Should be the same as Compressor1.Output!
returns a Null error
Summing up, I want Compressor1.Output and Compressor2.Input to refer to the same object.
What am I doing wrong?
The code is working as expected.
You never initialize Compressor1.Output. It therefore is null. You use this value as the input for the constructor of Compressor2, which is the value that you will then see in Compressor2.Input.
In other words:
Assert.Equal(Compressor1.Output, Compressor2.Input);
Assert.Null(Compressor1.Output);
Assert.Null(Compressor2.Input);
Thanks for the feedback! It made me look elsewhere
I used this:
public Refrigerant ShallowCopy()
{
return (Refrigerant)this.MemberwiseClone();
}
to copy the values stored inside my Refrigerant-class.
I thought this would just copy values so I didn't have to
Output.x = Input.x
Output.y = Input.y
Output.z = Input.z
But it didn't work as intended

Proper way to enforce business rules in property setter

Let's say an application has an Employer object has been created by a user and the program is prompting the user to enter in a property called EmployerId. In this example the application won't let the user enter in an invalid EmployeeId. I have mocked up the following solution to solve the problem.
public int EmployerId
{
get { return employerId; }
set
{
EmployerId = SetEmployerId();
}
}
public int SetEmployerId()
{
int id = 0;
Console.Write("Enter employer ID: ");
id = Convert.ToInt32(Console.ReadLine());
while (id < 5 || id > 10) //silly logic for illustrative purposes
{
Console.Write("Invalid id, enter another id: ");
id = Convert.ToInt32(Console.ReadLine());
}
return this.employerId = id;
}
this keeps any heavy lifting out of the setter of the property and delegates that responsibility to the SetEmployerId method.
Would this be an acceptable solution in a production setting? Is there any way this could be improved upon, or any pitfalls this might lead to later down the road when the application isn't such a contrived example? (besides the fact that the user isn't aware of what valid input is).
I think the better question is should an outside class be able to modify EmployerId directly.
Most often times methods that create mutation should exposed as verbs so something like ChangeEmployer(Employer newEmployer) and so on. Doing it that way make it more explicit and allows you to more easily raise domain events. In this case the set method would be private so that only the owning class can call it.
That said, any change of EmployerId should be verified in the setter that way the logic is only in one place and not strewn about multiple methods.
Karl Anderson's answer makes a very good point, that putting business logic in a setter like that prevents returning a non-exceptional error. This is true and should be taken into consideration before using property setters.
He also makes a good point about validation objects, your aggregate entities may only reference each other by Id as such having a separate business validation object for validating those Ids may be an excellent choice. You can reuse the validator in multiple places but at the end of the day the only place that matters is inside the entity, as that is the only place that must always be consistent.
public class Employee
{
private EmployerId employerId;
public Employee(EmployerId id /* other params such as name etc */)
{
var employerSetResult = this.SetEmployerId(id);
if(!result.Success)
throw new ArgumentException("id", "id is invalid");
}
// this is a separate method because you will need to set employerId
// from multiple locations and should only ever call SetEmployerId
// internally
public Result ChangeEmployer(EmployerId id)
{
var result = this.SetEmployerId(id);
if(result.Success)
DomainEventPublisher.Publish(
new EmployeeEmployerChanged(id, this.id));
return result;
}
private Result SetEmployerId(Employer id)
{
var result = EmployerIdValidator.Validate(id);
if(result.Success)
this.employerId = id;
return result;
}
}
public static class EmployerIdValidator
{
public static Result Validate(EmployerId id)
{
if(id < 5)
return new Result(success: false, new ValidationResult("Id too low"));
else if (id > 10)
return new Result(success: false, new ValidationResult("Id too high"));
return new Result(success:true);
}
}
public class Result
{
public bool Success {get {return this.success;}}
public IEnumerable<ValidationResult> ValidationResults
{
get{ return this.validationResults; }
}
}
One of the downsides of your approach is the inability to return "error" information about why the business rule failed. In your example you are directing output to the Console, which does the calling code no good.
I would recommend building a set of business rule classes that can be applied to your business objects and then processed upon an event (i.e. the presentation layer calls Validate on the business object) and then a collection (i.e. List<string> of errors) can be returned and used by the calling code (i.e. presentation layer).
I like approaches that Karl and Mgetz talked about.
Just wanted that if you want to use setters and getters and to separate your bussiness logic from presentation you doomed to use Exceptions and your code coud look like this:
public class WrongEmployeeIDException : Exception
{
public WrongEmployeeIDException(string message) : base(message) { }
}
public class Employee
{
private int employerId;
public int EmployerId
{
get { return employerId; }
set
{
if (value < 5 || value > 10)
{
throw new WrongEmployeeIDException("Invalid id");
}
employerId = value;
}
}
}
public void Main()
{
int id;
string input;
bool isSetted = false;
Employee employee = new Employee();
while (!isSetted)
{
Console.Write("Enter employer ID: ");
try
{
input = Console.ReadLine();
id = Convert.ToInt32(input);
employee.EmployerId = id;
isSetted = true;
}
catch (WrongEmployeeIDException ex)
{
Console.WriteLine(ex.Message);
//not satisfied to bussiness rules
}
catch (FormatException ex)
{
Console.WriteLine(ex.Message);
//Convert.ToInt32 thrown exception
}
catch
{
//something more bad happend
}
}
}
But it's not recommended aproach because validation logic will execute more smoothly and faster with Magetz's solution. It's something middle between your solusion and Magetz's.

method returning same object which was passed as parameter

Is it acceptable practice to pass an object into a method, then return the same object rather than creating a new object inside of the method itself?
As an example: if have an entity class as follows:
class UserDetails {
int UserID { get; set; }
string UserName { get; set; }
string UserAge { get; set; }
}
And then I pass an instance of this class to a method, as follows:
UserDetails UserInfo = new UserDetails();
UserInfo = Get_Details(UserInfo);
Is it reasonable for the method to do the following?
public UserDetails Get_Details(UserDetails user) {
// SQL Operations...
user.age = 32;
return user;
}
IMO, there is no need to return the object. Since it is passed to the method by reference, the caller already has a reference to the same object (with the updated values after the method completes).
On the other hand, what can be useful in some situations is a fluent-interface, where instance-methods of a class return the instance again, e.g:
class X
{
public X DoThis(int number)
{
// do something
return this;
}
public X DoThat(string name)
{
// do something else
return this;
}
}
This allows to write very readable code, such as:
var x = new X().DoThis(23).DoThat("asdf");
This can be useful with the builder pattern (when you want to build a complex object step by step).
As a very bad example:
class FooBuilder {
FooBuilder WithAge(int age);
FooBuilder WithUrl(Url url);
Foo ToFoo();
}
new FooBuilder().WithAge(12).WithUrl(new Url("http://www.happybirthday.com/").ToFoo();
In your particular case, I'd prefer to initialize everything in one go with the initializer syntax.
new User { Age = 45, UserName = "Bob", Id = 101 };
There is nothing horribly wrong with this but a couple of observations;
You are setting details inside of a method called get perhaps load is more appropriate.
If you are only passing in UserDetails because you want the id for your then the parameter should just be id instead. This keeps the interface cohesive.
It is generally considered bad form to modify a parameter object within a method, i.e., mutation principle.
Doing it like that is rather pointless, as the assignment that you do doesn't change anything.
Calling it like this:
UserInfo = Get_Details(UserInfo);
gives the same result as calling it and ignoring the return value:
Get_Details(UserInfo);
Returning the reference may only be confusing, leading someone to believe that the method returns a new instance, as that would be the only logical reason to return a reference.
It would make more sense to have that method in the class, so that you call it as:
UserInfo.Get_Details();
If your method is supposed to initialise the object, you would rather put the code it the constructor than calling it after creating the instance:
class UserDetails {
int UserID { get; set; }
string UserName { get; set; }
string UserAge { get; set; }
public UserDetails() {
Get_Details(this);
}
}
Then you just create the instance, and the constructor loads the data:
UserDetails UserInfo = new UserDetails();
This is a possible approach and when you have only ONE item to work one, the best, too. You might also consider to use ref, which creates a reference to the passed parameter
public void Get_Details(ref UserDetails user)
{
// SQL Operations. . .
user.age= 32;
}
this way, you don't pass a copy, but reference the object you passed in. But this can become quite obscure and is unnecessary in your case. See here for an insight.
You can fill your entity in its constructor method or another method inside entity class. It will be ready to use when created.
public class SomeClass
{
public string Field_1;
public int Field_2;
public SomeClass(int ID)
{
// Sql operations by ID or another value
// set fields
}
public AnotherMethod(int ID)
{
// Sql operations by ID or another value
// set fields
}
}
You might do well to look up the concepts of the Repository Pattern and OOD. In general, I prefer projections or fully loaded entities.
public UserDetailsProjection GetDetailsByUserId(Guid userID)
{
// Code goes here
return user;
}
Note: ref is not required, because all objects are passed by reference.

How to store the output of method?

I am looking for easy way to store the output of the method in some sort of variable so that it can be used by another class.
For example:
partial class Form1 {
public string orderNumber() {
string ord="ORD"+get_next_id()+DateTime.Now.Year;
return ord;
}
}
In an instance of Form1 user enter the purchase details such as name, address... and when user clicks add entry button, the details is saved in the database with ordernumber generated by above code. In meantime when user click add entry, it kills the current form and bring up the another form which uses the ordernumber generated earlier. When I do like
Form1 m=new Form1();
and do something like(following is pseudo code)
m.orderNumber=string orderNUm.
It generates different order number which I don't want. I want to use the ordernumber that was saved in the database by the Form1.
I want to store that ord somewhere so that I can pass it to another class.
Another class can use the result simply by calling the method itself:
public class A
{
public string orderNumber()
{
string ord = "ORD" + get_next_id() + DateTime.Now.Year;
return ord;
}
}
public class B
{
public void DoSomeWork()
{
A a = new A();
string result = a.orderNumber();
}
}
The notion of "storing it somewhere" feels like the concept of a global variable. While one can accomplish essentially the same thing, that is to be discouraged as that does not represent object oriented design principals.
Just to understand how you could do that in C# (you should not do this), you could do:
static public SharedStorage
{
public string OrderNumber { get; set; }
}
// Somewhere in your code
SharedStorage.OrderNumber = a.orderNumber();
// Somewhere else in your code
string orderNumber = SharedStorage.OrderNumber;
If you want to set an order number on an instance once and then use it going forward, you could put the logic in the constructor:
public class A
{
public string OrderNumber { get; private set; }
public A()
{
OrderNumber = "ORD" + get_next_id() + DateTime.Now.Year;
}
}
// Somewhere else in your code
A a = new A();
string orderNumber = a.OrderNumber;
This is fairly basic stuff, but add this to the top of the class:
public string OrderCode;
Next add OrderCode = ord; above the return ord; line
Now whenever someone needs the ordercode they just make a call to <YourClass>.OrderCode
However, they could just call the method itself to get the order number as it is public.
PS: the orderNumber method doesn't follow c# conventions. a) it should be properly capitalized (OrderNumber) and b) a more meaningful name would be GetOrderNumber

Multiple accessors for same value in c#

I have simple scenario where I have AnotherTest value based on Test value. This works fine most of the time so that whenever I provide Test I am sure to get AnotherTest easily.
public sealed class Transaction {
public string Test { get;set; }
public string AnotherTest{
get {
int indexLiteryS = Test.IndexOf("S");
return Test.Substring(indexLiteryS, 4);
}
}
}
However I wanted to be able to also set AnotherTest value and be able to read it without having to provide Test value. Is this possible? So kinda 2 types of get based which way it was set. I know I could create 3rdTest but I have some methods that use AnotherTest and other fields and I would have to write overloads of that methods.
Edit:
I read some file supplied by bank. I cut it in pieces put some stuff in Test value and every other field (AnotherTest and similar) of the Transaction gets filled automatically.
However later on I would like to read Transaction from SQL that is already in nice format so I don't need to provide Test to get the rest of the fields. I would like to set those fields with set and then be able to use get without setting Test value.
Yes, like so:
public string Test { get; set; }
public string AnotherTest
{
get
{
if(_anotherTest != null || Test == null)
return _anotherTest;
int indexLiteryS = Test.IndexOf("S")
return Test.Substring(indexLiteryS, 4);
}
set { _anotherTest = value; }
}
private string _anotherTest;
That getter could also be expressed as
return (_anotherTest != null || Test == null)
? _anotherTest
: Test.Substring(Test.IndexOf("S"), 4);
I think this would do what you want it to do:
public sealed class Transaction {
public string Test { get;set; }
public string AnotherTest{
get {
if (_anotherTest != null)
{
return _anotherTest;
}
else
{
int indexLiteryS = Test.IndexOf("S");
return Test.Substring(indexLiteryS, 4);
}
}
set {
_anotherTest = value;
}
}
private string _anotherTest = null;
}
I would suggest turning the problem over.
It sounds like you're dealing with a big field and subfields within it. Instead, how about promoting those subfields to fields and constructing/deconstructing the big field when it's accessed.

Categories