Basically put, I have something along the lines of:
public class Product
{
public int ID {Get;Set;}
public string foo {Get;Set;}
public string bar {Get;Set;}
public virtual SubProduct subproduct{get;set;}
public int SubProductID{get;set;}
}
public class SubProduct
{
public int ID {Get;Set;}
public string foo {Get;Set;}
}
I have a method that takes a string and does a search through foo -
var correctproduct = (db.product.SingleOrDefault(x => x.foo == my_string);
and, if it can find it, I use correctproduct, but, if it doesn't exist (checked via if correctproduct==null, I create a new object and perform .SaveChanges();.
However, I go straight on to the next part where I interact with subproduct. The part where I create the new object assigned a numerical value to subproduct, but, trying to expand, I just get Object reference not set to an instance of an object. The next time it is run, it works perfectly.
I have an idea where I can do a search for subproduct for id and assign the object to the subproduct property direct, but, I don't feel this is the best way. I also feel my use of SingleOrDefault is just a hack and was wondering if I can have some feedback on the best way of doing this?
You can use following code,
objectProduct.subProduct = new SubProduct{ ID = id,foo = value };
Related
Been looking for a way (either built-in, or through a plugin), to automate the properties and defaults when instantiating a class. For example, if I have the following:
public class MyClass
{
string MyPropertyString { get; set; }
int MyPropertyIntWithDefault { get; set; } = 5,
decimal? MyPropertyDecimalWithNoDefault { get; set; }
}
I'd love to be able to say MyClass MyClassImplemented = new MyClass {, hit a button or click an option, and have it automatically finish my code as:
MyClass MyClassImplemented = new MyClass {
MyPropertyString = "",
MyPropertyIntWithDefault = 5,
MyPropertyDecimalWithNoDefault = null
};
I'm guessing I could write an extension or tool myself using reflection, but if anyone has any suggestions that have already been implemented, I'd love to hear them. Thanks!
* EDIT *
To be clear, what I'm looking for is a way to automate the generation of that stub so that I can then change the ones I want to change, instead of having to either type them in manually or copy-paste them from the definition. I know that I can set default values so that I can generate the class with those values automatically.
All that you need is just creating a new instance of your class, then this new instance has all of the properties filled by their default value:
MyClass MyClassImplemented = new MyClass();
You just need to change your class a bit to set the properties a default value (don't forget to use ; after properties, however this works in C#6+):
public class MyClass
{
public string MyPropertyString { get; set; } = "";
public int MyPropertyIntWithDefault { get; set; } = 5;
public decimal? MyPropertyDecimalWithNoDefault { get; set; }
}
Based on your update, it seems what you are looking for, is a way to create a code snippet, so that you would be able to append the properties of the class by hitting some button, in this case you can create a code snippet in Visual Studio, you can go through this tutorial https://learn.microsoft.com/en-us/visualstudio/ide/walkthrough-creating-a-code-snippet?view=vs-2019
I have a search page which is using strongly typed objects, but I have the values broken into specific groups.
Code behind page calls the following when the user clicks the search button (none of these fields are empty):
SearchCriteria sc = new SearchCriteria();
sc.Generic.id = txtId.Text;
sc.Generic.maxReturned = rblMaxReturned.SelectedIndex;
sc.DisplayOnly.category = txtCategory.Text;
sc.DisplayOnly.type = txtType.Text;
sc.Building.address = txtAddress.Text;
sc.Building.city = txtCity.Text;
The DataType file is defined like this:
[Serializable]
public class SearchCriteria
{
public _Generic Generic { get;set; }
[Serializable]
public class _Generic
{
public int id {get;set;}
public int maxReturned {get;set;}
}
public _DisplayOnly DisplayOnly { get;set; }
[Serializable]
public class _DisplayOnly
{
public int category {get;set;}
public int type {get;set;}
}
public _Building Building { get;set; }
[Serializable]
public class _Building
{
public int address {get;set;}
public int city {get;set;}
}
}
When the code executes, I get a nullreferenceerror even though all the items in the various textboxes have a value. However, if I take out the public _Building Building { get;set; } and call the class directly it works and populates the values. What's the best solution here? Should I not use intermediary definition and call the class directly? If so, how can I call the different groups without making four different calls on the code behind page?
You need to initialize the internal class instances. Simply declaring the variables doesn't mean that you can access their properties without creating the instances. You could easily do that in the constructor of the SearchCriteria class
[Serializable]
public class SearchCriteria
{
public SearchCriteria()
{
// Without these initialization the internal variables are all null
// and so assigning any property of a null object causes the error
Generic = new _Generic();
DisplayOnly = new _DisplayOnly()
Building = new _Building();
}
.....
}
When you create a new instance of your SearchCriteria class, the properties are not initialized, and so they all have a value of null. So now look at the very first line where you try to use one of those properties:
sc.Generic.id = txtId.Text;
Here, txtID.Text is perfectly fine, but sc.Generic is null. When you try to look up the it's .id property for assignment, that's where the exception is thrown.
To fix this, you need to initialize each of those properties to have an instance of their type. Additionally, it's probably a good idea to use a private set, like so:
public _Generic Generic { get;private set; }
This will still allow to make all the same assignments that are currently written, because that only requires a get action to retrieve the type instance. The assignment/set operation is on the property of the property.
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.
I'm running into a ton of something that looks like this:
public class TestClass
{
public string Property1 {get;set;}
public string Property2 {get;set;}
public AddressType Type {get;set;}
[RequiredIf("", "", ErrorMessage="...")]
public int TypeId
{
get
{
if (Type == null)
return 0;
else
return Type.Id;
}
set
{
Type = new AddressType() { Id = value };
}
}
}
public class AddressType
{
public int Id {get;set;}
public string Description {get;set;}
}
so that I can model bind the info in a razor form and get binding back and forth. I'm wondering if there is anything out there that anyone knows where I can either apply an attribute against "AddressType" to set the default binding property for the class, or put an attribute against the 'Type' field of TestClass and say "When you bind, really bind to Type.Id, but validate against the whole object otherwise...
Not sure if I'm asking this right, but I just want a cleaner implementation if at all possible... I feel like adding the TypeId is unnecessary cruft in the class, and it makes it difficult to read.
Thx Guys!
Ok I'm not 100% across what you are asking here but I'll give it a go by assuming AddressType is nullable.
public class TestClass
{
public AddressType? Type {get;set;}
public int TypeId
{
get
{
return Type.HasValue ? Type.Value.Id : 0;
}
}
}
Looking at AddressType though I'm guessing that its a lookup type sourced from a datastore of some kind. I use T4 templates to generate these kinds of lookup lists (that don't change values between releases) as enums in my apps. Which if you do it will relieve you of a bunch of stress.
Now if what you want is a dropdownlist of AddressType values in your razor view you're going to have to do a little big of work in the controller (Not much thankfully)
public class BetterTestClass
{
public AddressType? Type {get;set;}
}
...In your AddressController
public ActionResult Create(){
// the name in the ViewBag should match
// the property you want to have a list on
ViewBag.Type = repository
.AddressTypes
.ToList()
.Select(p => new SelectListItem {
Key = p.Id,
Value = p.Description});
ViewData.Model = new BetterTestClass();
return View();
}
There are plenty of examples around if you search for #Html.DropDownList
EDIT
It's really difficult to work out what you are trying to achieve by your question. But I'll try and help. First do I understand your question correctly:
TestClass has a 0..1 relationship with AddressType
Address Type has an Id because it is an Entity class
For some reason you want the Id of AddressType to be set via the UI when AddressType is set. (which I outlined in my answer the inference being that you won't need required attributes)
This is probably a simple question. Suppose I have a object called Users and it contains a lot of protected variables.
Inside that Users class I have a method that creates a temporary Users object, does something with it, and if successful, transfers all the variables from the temp Users object into the one I have.
Is there some fast way to transfer all the variables from one Users object into another Users object without doing this using C#?
this.FirstName = temp.FirstName;
this.LastName = temp.LastName;
........75 variables later......
this.FavoriteColor = temp.FavoriteColor
A better approach is to implement the IClonable interface. But you'll find it doesn't save you a lot of work.
You should check out cloning in C#.
Deep cloning objects
I think serializing and then deserializing an object will create a new object instance. This should be identical to the former object.
A better solution might be to move whatever this method is outside of your class, and then just assign the temp user object to your main user object reference like so:
_User = tmpUser;
sparing you the 75 lines of code. Whenever I have a class creating an instance of itself inside one of its own methods, I always like to blink a couple of times and make sure I really need to be doing that.
There's always the reflection option. Something substantially similar to this:
public static void Copy(object source, object target)
{
foreach (System.Reflection.PropertyInfo pi in source.GetType().GetProperties())
{
System.Reflection.PropertyInfo tpi = target.GetType().GetProperty(pi.Name);
if (tpi != null && tpi.PropertyType.IsAssignableFrom(pi.PropertyType))
{
tpi.SetValue(target, pi.GetValue(source, null), null);
}
}
}
Doesn't require the source and the target to have any relation what-so-ever, just a name and an IsAssignable check. It has the interesting side effects if you're using reference types anywhere, but for the kind of situation you just described, this isn't a bad option to explore.
class sourceTester
{
public bool Hello { get; set; }
public string World { get; set; }
public int Foo { get; set; }
public List<object> Bar { get; set; }
}
class targetTester
{
public int Hello {get; set;}
public string World { get; set; }
public double Foo { get; set; }
public List<object> Bar { get; set; }
}
static void Main(string[] args)
{
sourceTester src = new sourceTester {
Hello = true,
World = "Testing",
Foo = 123,
Bar = new List<object>()
};
targetTester tgt = new targetTester();
Copy(src, tgt);
//Immediate Window shows the following:
//tgt.Hello
//0
//tgt.World
//"Testing"
//tgt.Foo
//0.0
//tgt.Bar
//Count = 0
//src.Bar.GetHashCode()
//59129387
//tgt.Bar.GetHashCode()
//59129387
}