Say Suppose you have a class
public class Person
{
public int PesronId{get;set;}
public string FirstName{get;set;}
public string LastName{get;set;}
public string Gender{get;set;}
}
Now We create an object p1
Person p1 = new Person();
Next we have values from textboxes to be assigned to p1
eg.
p1.PersonId = textbox1.text;
p1.FirstName = textbox2.text;
p1.LastName = textbox3.text;
Is there a more efficient way of doing this in Visual Studio 2010, by which I will get something like this
p1.PersonId =
p1.FirstName =
p1.LastName =
so that I dont have to manually type the properties for p1.
Or is then an alternate syntax that I can use.
There's simpler syntax for the code:
Person p1 = new Person
{
PersonId = textbox1.Text,
FirstName = textbox2.Text,
LastName = textbox3.Text
};
This is object initializer syntax, introduced in C# 3.
I think I'd misread the question though - it sounds like you're just interested in cutting down the typing required. There may be something which will do that, but personally I find IntelliSense is fine on its own. The readability of the code afterwards is much more important than the time spent typing, IMO.
You might also want to add a constructor to Person to take all the relevant property values - that would simplify things too, and with C# 4's named argument support, you can retain readability.
You can use the new initialization functionality in C#:
Person p1 = new Person()
{
PersonId = textbox1.text,
FirstName = textbox2.text,
LastName = textbox3.text
};
Related
When using Kotlin, one could use apply to set multiple properties of an existing object and keeping the code cleaner, for example instead of:
person.firstName = "John"
person.lastName = "Doe"
person.phone = "123 456 789"
We can use:
person.apply {
firstName = "John"
lastName = "Doe"
phone = "123 456 789"
}
Is there an equivalent to the apply in C#?
The closest to this is the using but it can't be used this way as far as I know.
Edit: I know of object initializer in C#, but I'm actually looking for something that can be done for existing objects (for example an object fetched from the database).
Try this.... https://dev.to/amay077/kotlins-scope-functions-in-c-pbn
Code pasted below for convenience, but the above link is the source...
static class ObjectExtensions
{
// Kotlin: fun <T, R> T.let(block: (T) -> R): R
public static R Let<T, R>(this T self, Func<T, R> block)
{
return block(self);
}
// Kotlin: fun <T> T.also(block: (T) -> Unit): T
public static T Also<T>(this T self, Action<T> block)
{
block(self);
return self;
}
}
Can be used like this....
var model = new MyModel().Also(m => {
m.Initialize();
m.Load(path);
});
You can use it in this way with object initializers:
var person = new Person
{
FirstName = "John",
LastName = "Doe",
Phone = "123 456 789"
};
Or with a constructor:
var person = new Person("John", "Doe", "123 456 789");
Your class would have to look like this for the constructor option:
class Person
{
public Person(string firstName, string lastName, string phone)
{
FirstName = firstName;
LastName = lastName;
Phone = phone;
}
public string FirstName { get;set; }
public string LastName { get;set; }
public string Phone { get;set; }
}
There is currently no support in C# (version 8) for grouped multi-property assignment outside of object initialization.
Similar support exists in VB.NET and has been proposed for C# 9.
Little bit of historical context
In Visual Basic.NET there is similar statement - With:
With person
.FirstName = "John"
.LastName = "Doe"
.Phone = "123 456 789"
End With
This one was carried from Visual Basic 6 for backward compatibility (previous, non .NET Version of language).
C# team (Anders Heilsberg himself told the story somewhere) argued that With statement decreases code readability and did not want to introduce it in the language. From what I have seen With statements can be nested and can creating quite a confusion of what is going on.
As many others have already mentioned, there is object initializer syntax that is quite similar:
var person = new Person
{
firstName = "John",
lastName = "Doe",
phone = "123 456 789"
};
Future - C# 9
As pointed out in another (deleted) answer, there is an open proposal for records and With expression, to be added in C# 9:
person with { firstName = "John", lastName = "Doe", phone = "123 456 789" };
Bonus Tip
However, most important advice I can give you, to avoid annoying fellow C# developer who might work on your code - we don't use camelCase in C# for public properties and methods, because C# is not Java. We use PascalCase! :)
With an object initializer:
var person = new Person
{
firstName = "John",
lastName = "Doe",
phone = "123 456 789"
};
After you already have the object, you can give yourself a short variable:
var p = person;
p.firstName = "Jane";
p.lastName = "Smith";
p.phone = "987 654 321";
//later:
Console.WriteLine(person.lastName); //will output "Smith"
which is less still less code than the apply option.
Object initializers allow you to do that but only at instanciation of an object.
Like
var person = new Person
{
FirstName = "John",
LastName = "Doe",
Phone = "123 456 789"
}
After copying Apply into several projects, i made a nuget package.
dotnet add package Object.Extensions.ScopeFunction
It offers extension methods Apply, ApplyForEach and Map (which lets you override return).
var permissionsMissingTestContext = new TestContext
{
Users = GetStandardUsers().ApplyForEach(x => x.Permissions = new Permission[0]),
SecurityPolicy = GetStandardSecurityPolicy().Apply(x => x.ShowWarningWhenPermissionsMissing = true),
AnonymousPageUrl = GetStandardConfig().Map(x => new Url(x.PermissionsMissingScreenUrl)),
Timeout = GetTestTimeout()?.Map(x => TimeSpan.FromSeconds(x)) ?? TimeSpan.FromSeconds(30)
}
Nuget
I'm programming in C# and I want to instantiate lots of new objects to my application, all of the same type, but with different values for their properties. Example:
Student student1 = new Student();
student1.Name = "James";
student1.Age = 19;
student1.City = "Los Angeles";
Student student2 = new Student();
student2.Name = "Karen";
student2.Age = 20;
student2.City = "San Diego";
Student student3 = new Student();
student3.Name = "Bob";
student3.Age = 20;
student3.City = "Dallas";
This way of coding seems really wrong to me because what if I didn't need 3, but 500 students? What would be the best way to do it then?
I tried to use a for loop for this but that doesn't work because the property values differ.
What is the most efficient way to do this?
Thanks in advance.
In order to do anything with your objects at runtime you will probably want them in a list.
Without reading from a file or database, etc., the most concise way might be :
var Students = new List<Student>{
new Student { Name = "Bob", Age = 22, City = "Denver" },
new Student { Name = "Sally", Age = 33, City = "Boston" },
new Student { Name = "Alice", Age = 12, City = "Columbus" }
};
I don't know your end goal however, is this just mock data, like for a test?
Add constructor to Student like this
Student (string name, int age, string city)
{
Name = name;
Age = age;
City = city;
}
///
Student student1 = new Student("James", 19, "Los Angeles");
Well, if what you mean by more efficient way to do it is just to write less code, you could instanciate them assigning the property's values at once, just like:
Student student1 = new Student() { Name = "James", Age = 19, City = "Los Angeles" };
If you want not just to write less code, but to - let's say - read the data from another source (like a Json list, or a TXT file) you will have to write a loader for it.
Well, it depends what you are going to use it for. If it’s for testing, then you could use a custom built tool to create random Students:
public class RandomStudentCreator
{
private readonly Random rnd = new Random();
private readonly IList<string> cities, names;
private readonly int minAge, maxAge;
public RandomStudentCreator(
IList<string> names,
IList<string> cities,
int minimumInckusiveAge,
int maximumExclusiveAge)
{
//Argument validation here
this.cities = cities;
this.names = names;
minAge = minimumInckusiveAge;
maxAge = maximumExclusiveAge;
}
public Student Next()
{
var student = new Student();
student.Name = names[rnd.Next(names.Count);
student.City = cities[rnd.Next(cities.Count);
Student.Age = rnd.Next(minAge, maxAge);
}
}
If this is production code, then you should be creating students based on:
User input
Some data backend (DB, text file, etc.)
But in any case, you don’t want to create a variable for each student. You probably want a collection of students. Depending on what you want to do with them, the type of collection you need may vary, the framework gives you plenty of options:
Arrays: Student[]
Lists: List<Student>
Queues: Queue<Student>
Stacks: Stack<Student>
Sets: HashSet<Student>
Etc.
And last but not least, you probably want to implement a constructor in Student that takes a name, city and age to make instantiation a little bit more compact than what you currently have:
public class Student
{
public Student(string name,
int age,
string city)
{
Name = name;
Age = age;
City = city;
}
//...
}
var john = new Student(“John”, 19, “LA”);
Programming is not about typing data. Need a lot of data? - Load them from files, databases, servers, through GUI, etc.
You can make a handy constructor, you can make factories and builders, but they are not for creating hundreds of objects in a row. Even if it is historical data, one day you will want to change them, fix something in them. Believe me, it's much easier to separate them from the code and store somewhere else, than to edit hundreds of lines of code later.
If you want 500 students I suggest extracting data to a file, database etc. student1..student499 implementation looks very ugly: let's organize them into array: Student[] students. As an example, let's use the simplest csv file Students.csv solution in the format
name,age,city
E.g.
name,age,city
James,19,Los Angeles
Karen,20,San Diego
Bob,20,Dallas
Having the file completed you can easily read it:
using System.IO;
using System.Linq;
...
Student[] students = File
.ReadLines("Students.csv")
.Where(line => !string.IsNullOrWhiteSpace(line)) // Skip empty lines
.Skip(1) // Skip header
.Select(line => line.Split(','))
.Select(items => new Student() {
Name = items[0],
Age = int.Parse(items[1]),
City = items[2], })
.ToArray();
im really new to C# so please excuse my sloppy code
public Kid(string name, int age, string location)
{
this.age = age;
this.name = name;
this.location = location;
}
NAL = Console.ReadLine().Split(',');
Console.WriteLine("Name-{0} Age-{1} Location-{2}", NAL);
string name = "Kid" + NAL[0];
Kid [name] = new Kid(NAL[0], Int32.Parse(NAL[1]), NAL[2]);
i need ^ this to work but i dont understand any of the types can some one help explain this to me
All you need to change is the "Kid" collection.
Dictionary<string, Kid> Kids = new Dictionary<string, Kid>();
Kids[name] = new Kid(NAL[0], Int32.Parse(NAL[1]), NAL[2]);
Using the Dictionary you can retrieve by name, adding an entry with the same name will overwrite the previous entry.
You can't dynamically name objects like you want to in C#. You can however implement something that meets your needs using a Dictionary.
var kids = new Dictionary<string, Kid>()
kids.Add(name, new Kid(NAL[0], int.Parse(NAL[1]), NAL[2]);
You can then access the Kid named Sam by doing
kids["KidSam"]
This gives you access to what are essentially named Kid objects without the need to name every object.
This is a noob question, I apologize. I have been trying for a while to figure out how to add an object to this array. I have an Employee class, and a Salary class that inherits from Emp, and an Hourly class that does. I created an array like this,
public Employee[] _Employees;
...
Employee[] _Employees = new Employee[]{
new Hourly("1000", "Harry","Potter", "L.", "Privet Drive", "201-9090", "40.00", "12.00"),
new Salary("2201", "A.", "A.", "Dumbledore", "Hogewarts", "803-1230", "1200"),
new Hourly("3330", "R.","Weasley", "R.", "The Burrow", "892-2000", "40", "10.00"),
new Salary("4040", "R.", "R.", "Hagrid", "Hogwarts", "910-8765", "1000")
};
And now I want to add objects to the array that I have read in from a text file. I am doing it like this right now;
if(rstring == "H")
{
string fullName = data.ReadLine();
string empNum = data.ReadLine();
string address = data.ReadLine();
string phoneNum = data.ReadLine();
string hrWorked = data.ReadLine();
string hrRate = data.ReadLine();
string[] splitName = fullName.Split(new Char[] { ' ' });
string fName = splitName[0];
string mName = splitName[1];
string lName = splitName[2];
_MyForm._Employees = new Employee[] {new Hourly ( empNum, fName, mName, lName, address, phoneNum, hrWorked, hrRate ) };
which doesn't give me any error, but when I look at what is stored in the _Employees class, it just has the info from above and nothing else. Let me know if I need to explain myself better. Just let me know if I need to go about it another way, or what I need to do to add the read info to this _Employees class.
Instead of having an array, you should consider using a List<Employee>. This will let you add any number of elements to the list, without recreating it yourself:
private List<Employee> employees = new List<Employee>();
public IList<Employee> Employees { get { return this.employees; } }
// ...
this.employees.Add(new Hourly("1000", "Harry","Potter", "L.", "Privet Drive", "201-9090", "40.00", "12.00"));
// .. Add all
Then, when you want to add a new one, you can use:
_MyForm.Employees.Add(new Hourly ( empNum, fName, mName, lName, address, phoneNum, hrWorked, hrRate));
You'd be better off using a List in this case:
IList<Employee> _Employees;
List has the advantage of having an Add method which can be used to add new objects to the end of the array.
_MyForm._Employees.Add(new Hourly(...))
If you wanted to insert objects at other points in the collection there's also the Insert method which takes an index along with the object to be added.
Use the List class as others have pointed out and the Add method. What you have done here:
_MyForm._Employees = new Employee[]
in your example code is you've re-assigned your reference of MyForm._Employees to a new object of type Employee[], not added to it. Your previous reference containing your other valuable employees will have most likely been garbage collected (if nothing else in scope is referencing it).
I would steer clear of arrays to be honest. See this for more information.
Question:
Hello All,
Sorry that this is kind of a noob question. I just don't know how to word this process, so I'm not sure what to Google for. I'll put some C# code below that should explain what I'm trying to do. I just don't know how to do it in VB. Additionally, for future ref, if you could tell me what this process is called, it would be helpful to know. Thanks in advance for your help.
// Here is a simple class
public class FullName
{
public string First { get; set; }
public char MiddleInintial { get; set; }
public string Last { get; set; }
public FullName() { }
}
/* code snipped */
// in code below i set a variable equal to a new FullName
// and set the values in the same line of code
FullName fn = new FullName() { First = "John", MiddleInitial = 'J', Last = "Doe" };
Console.Write(fn.First); // prints "John" to console
As I mentioned earlier, I am drawing blanks on what to search for so sorry if this question is a repeat. I too hate reruns :) So, please link me somewhere else if you find something.
Solution:
So thanks to the help of one of our members, I have found that the keyword is With.
Dim fn As New FullName() With { .First = "John", .MiddleInitial = "J"c, .Last = "Doe" }
Console.Write(fn.First) ' prints "John" to console
This is an Object Initializer.
The equivelent VB.NET code would be:
Dim fn = New FullName() With {.First = "John", .MiddleInitial = 'J', .Last = "Doe" }
The VB.NET reference is on MSDN.
This feature is named Object Initializers. See here: http://www.danielmoth.com/Blog/2007/02/object-initializers-in-c-30-and-vb9.html
They are known as object initializers. You can find more information on them here.