Check if class property has been set - c#

Lets assume I have a User class
public Class User
{
public string Name { get; set; }
public string Surname { get; set; }
public int Level {get;set;}
}
User user1 = new User();
user1.Name = "name";
user1.Surname = "Surname";
user1.Level = 0;
User user2 = new User();
user2.Name = "name";
user2.Surname = "Surname";
When I check user1.Level == user2.Level it returns true since default int value is 0.
So is there any way to do that I can understand that Level property of user2 is not set so that I can say these two are not identical?

1) If you use int? as type for Level, it will be NULL when not setted.
public Class User
{
public string Name { get; set; }
public string Surname { get; set; }
public int? Level {get;set;}
}
2) you can use the setter of the level attribute and set a boolean when you set a new value, if the other proposed solution is not good for you. Example:
public Class User
{
public string Name { get; set; }
public string Surname { get; set; }
private int _Level;
public int Level
{
get { return _Level; }
set { _Level= value; _hasLevel = true; }
}
public bool HasLevel { get { return _hasLevel; } }
}

Another option (in addition to the others suggested) is to set the value to something other than 0 in the class constructor. It's common to use -1.
public Class User
{
public User()
{
Level = -1;
}
public string Name { get; set; }
public string Surname { get; set; }
public int Level {get;set;}
}

Use Nullable
public Class User
{
public string Name { get; set; }
public string Surname { get; set; }
public int? Level {get;set;}
}
It will have by default value null instead of value 0.
for more about Nullable look at msdn documentation

You can change your class to make Level nullable.
public class User
{
public string Name { get; set; }
public string Surname { get; set; }
public int? Level {get;set;}
}

Related

setting value of a property in source list

I have 2 lists
public class EmailDetails
{
public int EmailMasterID { get; set; }
public string Name { get; set; }
public string Body { get; set; }
public string Number { get; set; }
public string IsModified { get; set; }
}
public class EmailDetailsActual
{
public string ProgramNumber { get; set; }
public string IsModified { get; set; }
public int EmailMasterID_FK { get; set; }
}
I need to set value of IsModified column to YES in EmailDetails list if EmailMasterID = EmailMasterID_FK (from EmailDetailsActual list) . If not, then set value to NO. The final result should be EmailDetails list.
im not sure but i put new EmailDetailsActual in EmailDetails and I put the details for that (ProgramNumber , IsModified , EmailMasterID_FK)
and then I put input to when Call EmailDetails , should fill inputs like
EmailDetails p1 = new EmailDetails("ProgramNumber", "IsModified", 0000);
after i put IsModified Get properties in EmailDetails >>
if (EmailMasterID == EDA.EmailMasterID_FK)
{
return "yes";
}
else
{
return "no";
}
// EDA is new EmailDetailsActual
And I accessed it values ​​in a this way (accessed EmailMasterID_FK (we create new EmailDetailsActual ) )
and its my finally >>>
public class EmailDetails
{
EmailDetailsActual EDA = new EmailDetailsActual();
public EmailDetails(string ProgramNumber , string IsModified , int EmailMasterID_FK)
{
EDA.ProgramNumber = ProgramNumber;
EDA.IsModified = IsModified;
EDA.EmailMasterID_FK = EmailMasterID_FK;
}
public int EmailMasterID { get; set; }
public string Name { get; set; }
public string Body { get; set; }
public string Number { get; set; }
public string IsModified { get
{
if (EmailMasterID == EDA.EmailMasterID_FK)
{
return "yes";
}
else
{
return "no";
}
}
}
}
public class EmailDetailsActual
{
public string ProgramNumber { get; set; }
public string IsModified { get; set; }
public int EmailMasterID_FK { get; set; }
}
this is example to work >>
EmailDetails p1 = new EmailDetails("ProgramNumber", "IsModified",9991);
p1.EmailMasterID = 9992;
Console.WriteLine(p1.IsModified);
its output no bc EmailMasterID (9991) its not same with EmailMasterID_FK(9992)
I hope I able to help you :)

AutoMapper returns NULL when returning a list

Code without AutoMapper:
List<CountryDM> countryDMList = _countryRepo.GetCountry();
List<CountryVM> countryVMList = new List<CountryVM>();
foreach (CountryDM countryDM in countryDMList)
{
countryVMList.Add(CountryVM.ToViewModel(countryDM));
}
return countryVMList;
I used AutoMapper for the above task. But it returns a NULL list. Please refer the below code:
List<CountryDM> countryDMList = _countryRepo.GetCountry();
Mapper.CreateMap<List<CountryDM>, List<CountryVM>>();
List<CountryVM> countryVMList = new List<CountryVM>();
return Mapper.Map<List<CountryVM>>(countryDMList);
public class CountryDM
{
public int ID { get; set; }
public string CountryCode { get; set; }
public string Description { get; set; }
}
public class CountryVM
{
public int ID { get; set; }
public string CountryCode { get; set; }
public string Description { get; set; }
}
You don't need to define a mapping between lists, just between objects, AutoMapper will know how to extrapolate that:
Mapper.CreateMap<CountryDM, CountryVM>();
the rest stays the same

c# convert existing class to use properties correctly

I have the following classes:
class Given
{
public string text = "";
public List<StartCondition> start_conditions = new List<StartCondition>();
};
class StartCondition
{
public int index = 0;
public string device = "unknown";
public string state = "disconnected";
public bool isPass = false;
};
I want to convert them into c# properties (using get; and set;)
Looking at this question: what-is-the-get-set-syntax-in-c, it seems I can make a property nice and easy like this:
class Given
{
public string text { get; set; }
public List<StartCondition> start_conditions { get; set; }
};
class StartCondition
{
public int index { get; set; }
public string device { get; set; }
public string state { get; set; }
public bool isPass { get; set; }
};
But now I don't know how I should add my initialisations, because I want the same start values as I had before, or for the List container I want it to be new'ed.
What is the best way to achieve this?
The ability to have auto property initializers is included since C# 6.0. The syntax is:
public int X { get; set; } = x; // C# 6 or higher
Use a constructor. So your class would look like this:
public class StartCondition
{
public int index { get; set; }
public string device { get; set; }
public string state { get; set; }
public bool isPass { get; set; }
// This is the constructor - notice the method name is the same as your class name
public StartCondition(){
// initialize everything here
index = 0;
device = "unknown";
state = "disconnected";
isPass = false;
}
}
Create a Constructor to start your class instance with the default values
class Given
{
public Given(){
this.text = "";
start_conditions = new List<StartCondition>();
}
public string text { get; set; }
public List<StartCondition> start_conditions { get; set; }
};
class StartCondition
{
public StartCondition(){
this.index = 0;
this.device = "unknown";
this.state = "disconnected";
this.isPass = false;
}
public int index { get; set; }
public string device { get; set; }
public string state { get; set; }
public bool isPass { get; set; }
};
Now you can create your instances with the default values by using StartCondition A = new StartCondition();
If you are not using C# 6+ (or even if you are), you can explicitly declare your backing variables for properties:
public class Given
{
private string _text = string.Empty;
private List<StartCondition> _start_conditions = new List<StartCondition>();
public string text { get{ return _text; } set{ _text = value; } }
public List<StartCondition> start_conditions { get{ return _start_conditions; } set{ _start_conditions = value; } }
}
This allows you to set your initializations as before.

C# Accessing a methods value dynamically using a string

I am currently setting some strings via this method:
string marketlabel = allmarketdata.#return.markets.COLXPM.label.ToString();
I would like to set the market label dynamically by having a string for the actual market choice.
string currentMarketSelected= this.marketTextBox.Text; // Specific market: COLXPM
string marketlabel=allmarketdata.#return.markets.currentMarketSelected.label.ToString();
I have been searching for a few hours and probably am not explaining correctly. I tried some stuff with reflections with no success. Basically what I want to do is have a textbox or list which contains all the market names and based on which one is selected start setting the data.
Above is the best type of example of what I want to do even though it is not syntactically possible to use a variable in place.
public class Markets
{
public COLXPM COLXPM { get; set; }
//Lots of markets below here
}
public class COLXPM
{
public string marketid { get; set; }
public string label { get; set; }
public string lasttradeprice { get; set; }
public string volume { get; set; }
public string lasttradetime { get; set; }
public string primaryname { get; set; }
public string primarycode { get; set; }
public string secondaryname { get; set; }
public string secondarycode { get; set; }
public List<Recenttrade> recenttrades { get; set; }
public List<Sellorder> sellorders { get; set; }
public List<Buyorder> buyorders { get; set; }
}
public class Return
{
public Markets markets { get; set; }
}
public class RootObject
{
public int success { get; set; }
public Return #return { get; set; }
}
The proposed solution below that worked
string currentMarketSelected = "DOGEBTC"; // Just selecting one of the markets to test it works
var property = allmarketdata.#return.markets.GetType().GetProperty(currentMarketSelected);
dynamic market = property.GetMethod.Invoke(allmarketdata.#return.markets, null);
string marketlabel = market.label.ToString(); //Gets all my selected market data
Here is a solution using reflection.
string currentMarketSelected= this.marketTextBox.Text; // Specific market: COLXPM
var property = allmarketdata.#return.markets.GetType().GetProperty(currentMarketSelected);
dynamic market = property.GetGetMethod().Invoke(allmarketdata.#return.markets, null);
string marketlabel=market.label.ToString();
You need something like this:
public class Markets
{
public COLXPM this[string key]
{
get
{
COLXPM colxpm;
switch (key)
{
// TODO : use "key" to select instance of COLXPM;
case "example1":
colxpm = ...;
break;
default:
throw new NotSupportedException();
}
return colxpm;
}
}
}
Then you can do something like:
string marketlabel=allmarketdata.#return.markets[currentMarketSelected]label.ToString();
This is an indexed property.

A simple OOP understanding

I have a class:
public class TaskDiplayModel
{
public int taskId { get; set; }
[DisplayName("Task Description")]
public string description { get; set; }
[DisplayName("Priority")]
public string priority { get; set; }
[DisplayName("State")]
public string state { get; set; }
[DisplayName("Due By")]
public DateTime deadline { get; set; }
[DisplayName("Created By")]
public PersonObject created_by { get; set; }
[DisplayName("Assigned To")]
public PersonObject assigned_to { get; set; }
[DisplayName("Category")]
public string category { get; set; }
[DisplayName("Sub Category")]
public string subCategory { get; set; }
[DisplayName("Created")]
public DateTime createdDate { get; set; }
[DisplayName("Updated")]
public DateTime lastUpdatedDate { get; set; }
[DisplayName("Updated By")]
public PersonObject lastUpdatedBy { get; set; }
}
I then have another class which inherits from this class:
public class TaskModifyModel : TaskDiplayModel
{
public int priorityId { get; set; }
public int stateId { get; set; }
public int categoryId { get; set; }
public int subCategoryId { get; set; }
public SelectList states { get; private set; }
public SelectList priorities { get; private set; }
public SelectList categories { get; private set; }
public SelectList subCategories { get; private set; }
public TaskModifyModel()
{
SetupReferenceData(0);
}
public TaskModifyModel(int taskId)
{
var taskService = new TaskService();
var task = taskService.GetTask(taskId);
}
}
In my application, I create a TaskModifyModel object. However, string fields from the base class are null. I'd expect them to have been created and be String.Empty. But I get exception when I try to access them. Am I missing something?
These are MVC3 Models, by the way.... And code from the classes have been omitted as I think it's irrelevant to the question.
in .NET, the default value for a string is null, not String.Empty, so unless you specifically set the values of the properties to String.Empty, they will remain null.
Assuming you want your string properties to default to an empty string instead of null, you would normally do this either by setting them in the constructor:
public void TaskDiplayModel()
{
description = String.Empty;
priority = String.Empty;
state = String.Empty;
}
Or by using a field-backed property instead of an auto property, and setting the backing field:
private string _description = String.Empty;
[DisplayName("Task Description")]
public string description
{
get { return _description; }
set { _description = value; }
}
Personally I usually use the first option, doing it in the constructor, because it is less to code.
Just to add to rally25rs' excellent answer (+1 from me anyway), given the following abridged version:
public class TaskDiplayModel
{
private string _priority = string.Empty;
public int TaskId { get; set; }
public string Description { get; set; }
public string Priority
{
get { return _priority; }
set { _priority = value; }
}
public TaskDisplayMode()
{
Description = string.Empty;
}
}
public class TaskModifyModel : TaskDisplayMode
{
public int PriorityId { get; set; }
public TaskModifyModel()
:base()
{
PriorityId = 3;
}
}
Then the order upon construction of TaskModifyModel is as follows:
Set _priority to string.Empty, TaskId to 0, PriorityId to 0, and Description to null (if no value is stated, everything gets set to null if a reference, 0 if a number, and structs get set to having their fields full of 0 and null).
If the constructor body of TaskDiplayModel is executed, setting Description to string.Empty.
The constructor body of TaskModifyModel is executed, setting PriorityId to 3.
And so on if the nested inheritance is more complicated. As a rule, you can expect some of this to be optimised, so don't worry about whether it would be faster or slower to take a different approach as to how you set a value - it won't, except in debug runs. It does though explain the rule of avoiding calling virtual methods within constructors - most of the time we don't need to care about the ordering above and just treat the constructor as a single unit after which we have a fully constructed object, but if you start playing with virtual calls then the above ordering becomes very important because at one point PriorityId is 0, and at another its 3.

Categories

Resources