Should I assign object properties when initializing or after initializing? [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have an object obj1 with 11 properties.
Is it better to do this
Obj obj1 = new Obj()
{
prop1 = int.Parse(data.Rows[0]["RequestId"].ToString())
prop2 = IsBoss = (bool)data.Rows[0]["IsBoss"]
///etc...
}
or should I do
{
Obj obj1 = new Obj(){}
obj1.prop1 = int.Parse(data.Rows[0]["RequestId"].ToString())
obj1.prop2 = IsBoss = (bool)data.Rows[0]["IsBoss"]
///etc...
}
Also as a side question, when my data rows are null, an exception "Input string was not in a correct format" gets thrown because the field from the database is null. Typically the data wouldnt be null but would it be best to use a ternary operator to check if null or should i do a case in the sql qry.

Like the other answers, how you instantiate an object is up to you. Personally, I used to instantiate them and assign the properties all in one statement. The issue that I kept running into is when a had a property that failed to make it back from the database (like your null exception scenario), the the exception wouldn't give me an accurate line number. For that reason, I've moved to instantiating the object, then assigning the properties. This way, you'll know exactly which line/property is causing the issue.
MyClass obj = new MyClass();
obj.PropertyOne = "";
obj.PropertyTwo = "";
//etc...
As far as your second question goes, I handle nulls by using a ternary in combination with the IsDBNull() method on the DataTableReader.
MyClass obj = new MyClass();
obj.PropertyOne = rdr.IsDBNull(rdr.GetOrdinal("RequestId")) ? 0
: rdr.GetInt32(rdr.GetOrdinal("RequestId"));

I prefer setting object properties on initialization as per the first example, I think the code looks cleaner and better contained, but that is more of a personal preference.
For your second question when data is null coming back from the database you've got a few options.
{
var obj1 = new Obj()
{
prop1 = int.TryParse(data.Rows[0]["RequestId"]?.ToString(), out int val) ? val : -1,
prop2 = IsBoss = bool.TryParse(data.Rows[0]["IsBoss"].ToString(), out bool isBoss) ? isBoss : false
}
}
Haven't tested but something like that should work, but it's not clean. I'd separate out the parsing into its own method or block. To help the code breathe a little.
Something like this:
{
if(!(int.TryParse(data.Rows[0]["RequestId"]?.ToString(), out int requestId)))
{
requestId = -1;
}
bool.TryParse(data.Rows[0]["IsBoss"]?.ToString(), out IsBoss);
var obj1 = new Obj()
{
prop1 = requestId,
prop2 = IsBoss
}
}

Related

Change property value of a C# Dynamic type [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Is there any way to change a dynamic type property value ?
Code Example:
dynamic result = new { Status = "WARNING", Modified = false, Message = string.Empty };
result.Status = "OK";
Is that possible at all using C# ?
Thanks
Dynamic data type is added in c# 4.0. It is used to avoid the compile-time type checking. The compiler does not check the type of the dynamic type variable at compile time, instead of this, the compiler gets the type at the run time.
Though, in most cases, dynamic data type behaves like an object.
In the abovementioned example:
You've created an anonymous type variable which is like the class type but it can only include public read-only members so you can't change result.Status value in this case.
TO SOLVE THE PROBLEM :
I think you should use generic collection like dictionary
The code may look like this:
var result = new Dictionary<string, object>() { {"Status", "Warning"}, {"Modified", false}, {"Message", string.empty} };
result ["Status"] = "Ok";
No this is not possible. You will get a runtime error telling you that the property Status of the anonymous type is write protected or read-only.
For future use here is the online compiler proof:
The documentation says:
Anonymous types contain one or more public read-only properties.
You would need to recreate the object again using the values from the original one for the rest of the properties:
var result = new { Status = "WARNING", Modified = false, Message = string.Empty };
result = new { Status = "OK", Modified = result.Modified, Message = result.Message };
Console.WriteLine(result.Status);
Output:
OK

Why is my getter being called until there is a StackOverflow? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I use a generic list in my Winforms app, and had code throughout where I would first check if the underlying (json) file existed and, if it did, deserialize it, and then access the deserialized generic list. I decided it would be better to put that code in one place, so did this:
public static List<AssignmentHistory> assignmentHistList
{
get { return GetAssignmentHistoryList(); }
}
public static List<AssignmentHistory> GetAssignmentHistoryList()
{
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME)) return null;
if (null == assignmentHistList)
{
return DeserializeAssignmentHistFile();
}
return assignmentHistList;
}
public static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
var assignmentHistFile = System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized = JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHist);
return assignmentHistDeserialized;
}
I then call it like so:
AssignmentHistory ah =
AYttFMConstsAndUtils.assignmentHistList.FirstOrDefault(
i => i.WeekOfAssignment == currentWeek && i.TalkType == 1);
...but never get beyond that line, as GetAssignmentHistoryList() gets called over and over again until there is a stack overflow. What am I doing wrong here?
UPDATE
I used abto's null coalescing operator suggestion, but to prevent against the possibility of an empty file, I had to also modify my Deserialize method, so that it is now:
private static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
List<AssignmentHistory> assignmentHistoryList;
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME))
{
var assignmentFile = System.IO.File.Create(ASSIGNMENT_HISTORY_FILENAME);
assignmentFile.Close();
}
var assignmentHistFile = System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized = JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHistFile);
if (null != assignmentHistDeserialized) return assignmentHistDeserialized;
assignmentHistoryList = new List<AssignmentHistory>();
return assignmentHistoryList;
}
Because there are already answers why your code fails, I wanted to post a possible fix to your code:
// this is the backing field for your property
private static List<AssignmentHistory> assignmentHistList;
// it is good practice to name properties starting uppercase
public static List<AssignmentHistory> AssignmentHistList
{
get
{
// return the content of the backing field if is not null
return assignmentHistList ??
// in case the backing field is null,
// assign it a value from your deserialize method
// and than return it
(assignmentHistList = DeserializeAssignmentHistFile());
}
}
private static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
// If the file which should contain your data does not exist (yet) return null,
// the property will retry to set the backing field the next time it is accessed
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME)) return null;
var assignmentHistFile
= System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized
= JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHist);
return assignmentHistDeserialized;
}
Then you can call it (mostly) like you wanted:
AssignmentHistory ah = AYttFMConstsAndUtils.AssignmentHistList
.FirstOrDefault(i => i.WeekOfAssignment == currentWeek && i.TalkType == 1);
Remember that this will throw an ArgumentNullException if the file from which should be deserialized does not exist.
Label1:
The assignmentHistList property's getter invokes GetAssignmentHistoryList() which recursively invokes assignmentHistList property's getter.
goto Label1;
You might have wanted the property to be called AssignmentHistList with upper-case A, in-line with the common code style practice, and having a private static field assignmentHistList. Anyway, the duality of existence of a property X and a GetX() method is wierd.
Stackoverflow exceptions usually occur due to Recursive call condition that was not detected right.
Only by observing the following code, we can deduce their is a visious circular calls.
assignmentHistList -> GetAssignmentHistoryList, which checks the condition null == assignmentHistList but in order to check this condition it needs to enter (Recursion) for assignmentHistList again, which will then call GetAssignmentHistoryList again.. And you can see where this is going.
public static List<AssignmentHistory> assignmentHistList
{
get { return GetAssignmentHistoryList(); }
}
public static List<AssignmentHistory> GetAssignmentHistoryList()
{
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME)) return null;
if (null == assignmentHistList) << Here is another call to the Getter
// The rest is not important
}

copying one objects data to other? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to update EF record, in method I have EF object and another new objct which I want to use to update data from. But I m not sure how to copy data from new object to existing one.
Help please.
Here is my code:
public int PostHomeLead(string _lead)
{
try
{
int result = 0;
Lead lead = new Lead();
lead = new JavaScriptSerializer().Deserialize<Lead>(_lead);
//check if lead exist with same session id, if so update it other wise add new.
Lead existingLead = new Lead();
existingLead = db2.HomeLoanCustRepo.GetByID(lead.Lead_id);
if (existingLead == null)
{
db2.HomeLoanCustRepo.Insert(lead);
db2.Save();
result = 1;
}
else
{
db2.HomeLoanCustRepo.Update(lead);
db2.Save();
result = 1;
}
return result;
}
catch(Exception ex)
{
throw ex;
}
}
Either map the properties manually:
existingLead.Foo = deserializedLead.Foo;
existingLead.Bar = deserializedLead.Bar;
existingLead.Baz = deserializedLead.Baz;
Or use a library that does this, like AutoMapper.
As for your comment, creating a deep copy is what you seem to be after. Note this allows for overposting or mass assignment when you don't verify which properties may be updated. You'll need to Attach() the cloned object when using cloning or mapping, as it will not be the same object as returned by GetByID(), so Entity Framework's change tracker won't recognize it.

How can I do a cast that involves var? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I’m trying to do a cast that involves var. I have initialized my variable like this:
var updateContent = (MyType)null;
if (correctTime)
{
var getDataFromDatabase = from d in db.Content where d.someId == id select d;
//Here's where my I need to do some type of cast.
updateContent = getDataFromDatabase
}
Is there a correct cast that I can use to store getDataFromDatabase in updateContent?
UPDATE:
Sorry my questions was unclear. Based on all your comments I was able to accomplish the following:
IEnumerable<MtType> updateContent = null;
if (correctTime==true)
{
IEnumerable<MtType> getDataFromDatabase = var getDataFromDatabase = from d in db.Content where d.someId == id select d;
updateContent = getDataFromDatabase;
}
My final objective was to be able to access returns from inside an if block and this did the trick. Thanks again for all your help.
The result from you query will be an IEnumerable<Content>. If you want to load the results from your query into MyType then you need to do a projection like this:
var getDataFromDatabase = from d in db.Content where d.someId == id
select new MyType { Prop1 = d.Prop1, Prop2 = d.Prop2 };
This will give you an IQueryable<MyType>, which in turn inherits IEnumerable<MyType>, in getDataFromDatabase
If you just want to get the the first MyType from you query results, then you can do:
updateContent = getDataFromDatabase.FirstOrDefault();
The keyword var is just a handy abbreviation for the concrete type. It is not something like a dynamic type or so. As quite a lot of commentors stated before, the two following lines are identical
var myVar1 = (MyType)null;
MyType myVar2 = (MyType)null;
The only difference is that the typecast can be ommited in the second line. So, and this was mentioned as well, you are trying to assign an IEnumerable<OfSomeType> to a variable of MyType which simply does not and will never work.
Resharper's refactoring options allow you to switch between implicit (var) and explicit (MyType) declaration.
I assume that in the code following what you posted there's a check to see if updateContent is null.
This seems like a really good application of the conditional operator:
var updateContent = correctTime
? (from d in db.Content where d.someId == id select d)
: null;

C# get name of object as string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have an object named 'Account' and the following code:
Account objAcc = new Account();
objAcc.Name = "Test";
The above is working fine, as expected. I now have a list of values as follows:
string props = "Name,Address,Telephone";
Now, what I want to do is see if "Name" exists in that list. I only have the object to use though (hard coding a case statement etc isn't possible as the object is dynamic), so from objAcc.Name, I somehow need to get "Name" from that, and then see if it's in the list.
Thanks in advance, I hope it's clear enough,
Dave
You can use reflection, by doing that :
var properties = objAcc.GetType().GetProperties();
foreach(var property in properties)
{
if(props.Contains(property.Name))
{
//Do you stuff
}
}
string test = objAcc.GetType().GetProperty("Name") == null ? "" : objAcc.GetType().GetProperty("Name").Name;
bool result = "Name,Address,Telephone".Split(',').Contains(test);
You may use the following method if you like:
public bool PropertyExists<T>(string propertyName, IEnumerable<string> propertyList,T obj)
{
string test = obj.GetType().GetProperty(propertyName) == null ? "" : obj.GetType().GetProperty(propertyName).Name;
bool result = propertyList.Contains(test);
return result;
}
Giannis

Categories

Resources