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.
Related
I just want to check if my RepoItemInfo object (which is username Joe McAdam btw) is equal to string data.
I just tracked this element in Chrome, stored it in my repository and it is a span with #innertext="JoeMcAdam"
Then I made code module for mapping these objects in C# code:
public RepoItemInfo LeftNameRepoItem {get {return _pageHome.Home.ImeLijevoInfo; }}
And I have prepared data Name in my context file for this LeftName to check if they are equal:
void ITestModule.Run()
{
var dto = new LoginDto () {
Name = "Joe McAdam",
WaitTimeLimit = 20000,
};
LoginDtoContext.template = dto;
}
I just need a proper code example for checking if they are eqal. What should I do? Do I have to make some adapter for this RepoItemInfo to convert it in string, text or something else?
I hope I provided enough details about my problem.
Thanks in advance!
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 created a text file and I am storing data to that file. Each word is separated by '-'
word1-word2-word3-word4.
Moreover, I am using DataGridView(control) to display each word in a separate column.
I want to remove specific line from text file where lets say 'word1' and 'word2' match to the given variables
public static string word1;
public static string word2;`
I am trying to implement below code but not getting proper solution to do that. please help. I am newbie to C#...
public static string word1; //static to access in another form
public static string word2;
if (e.ColumnIndex == 5) //view
{
string[] lines = File.ReadAllLines(#"info.txt");
word1 = dataGridViewF.Rows[e.RowIndex].Cells[0].Value.ToString();
word2= dataGridViewF.Rows[e.RowIndex].Cells[1].Value.ToString();
string[] newLines = lines.Where(line => !line.Contains(word1));
using (StreamWriter file = new StreamWriter(#"info.txt", true))
{
File.WriteAllLines(#"info.txt"", newLines);
}
}
Your example text line:
FirstName-LastName-age-MobileNo.
Is a big indicator that you are likely using the wrong approach. If a - delimits your data, what happens when a phone number has a - in it? What happens when a nice married person has a - in their new last name? Can you see how this would be problematic?
A better approach (as mentioned in the comments) would be to serialize your data into a format designed for this. I will use Json in my example.
First you should create a class that describes your data:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MobilePhoneNumber { get; set; }
public int Age { get; set; } //Really should be storing birthday instead...
}
When you serialize this object into json it would look like this:
{
"FirstName": "John",
"LastName": "Doe",
"Age": 42,
"MobilePhoneNumber": "(123) 456-7890"
}
And a list of these will look like:
[{
"FirstName": "John",
"LastName": "Doe",
"Age": 42,
"MobilePhoneNumber": "(123) 456-7890"
},
{
"FirstName": "Jane",
"LastName": "Sanders-Doe",
"Age": 69,
"MobilePhoneNumber": "(890) 555-1234"
}]
So now your code for getting this data is pretty simple (Ill use Json.NET -- the standard library for this):
string json = File.ReadAllText(#"info.json");
List<Person> persons = JsonConvert.DeserializeObject<List<Person>>(json);
Now that you have actual objects to work with, your code is much cleaner and less error prone:
string fName = dataGridViewF.Rows[e.RowIndex].Cells[0].Value.ToString();
string lName = dataGridViewF.Rows[e.RowIndex].Cells[1].Value.ToString();
string json = File.ReadAllText("info.json");
//'deserializes' which just means turns JSON into a real object
List<Person> persons = JsonConvert.DeserializeObject<List<Person>>(json);
//'persons' is now a list of Persons who's names DONT match
//in other words the names that matched are removed from the output
persons = persons.Where(x => x.FirstName != fName && x.LastName != lName).ToList();
//'serialize' means turns an object into a json string
json = JsonConvert.SerializeObject(persons);
File.WriteAllText("info.json", json);
Note that I made the code a bit verbose so you could understand. A lot of the above lines can be condensed into less lines.
This is the best way to do it providing that you are getting fName and lName correctly:
string[] lines = File.ReadAllLines(#"info.txt"); //original file
fName = dataGridViewF.Rows[e.RowIndex].Cells[0].Value.ToString();
lName = dataGridViewF.Rows[e.RowIndex].Cells[1].Value.ToString();
var iter = lines.Where(line => {
string[] name = line.Split('-');
string f = name[0];
string l = name[1];
if(f.ToLower().Equals(fName.ToLower()))
if (l.ToLower().Equals(lName.ToLower()))
{
return false;
}
return true;
});
File.WriteAllLines(#"D:\\newfile.txt", iter.ToArray()); //put them in newfile.txt, don't delete the original one which is info.txt
Piece of advice: Don't use - as a delimiter. Because mobile numbers might contain dashes as well. I suggest you change the delimited to become a comma ,. However, FirstName and LastName being your first two params, won't affect your case. But in general, you want to use a delimiter that you know for sure it won't exist within your values.
I am trying to serialize a list to json string using Json.NET but the return string has backslash within it, which in turn is failing a json parsing.
var x = from d in entities.Books.ToList()
select new
{
ID = d.ID,
BookName = d.BookName
};
return JsonConvert.SerializeObject(x.ToList());
The above code returns
"[{\"ID\":1,\"BookName\":\"MVC Music Store - Tutorial - v3.0\"},{\"ID\":2,\"BookName\":\"Pro.ASP.NET.MVC.3.Framework\"},{\"ID\":3,\"BookName\":\"Application Architecture Guide v2\"},{\"ID\":4,\"BookName\":\"Gang of Four Design Patterns\"},{\"ID\":5,\"BookName\":\"CS4 Pocket Reference\"}]"
which fails all JSON parsing. How can I remove these.
No. it doesn't
class Program
{
class Book
{
public int ID;
public string BookName;
}
static void Main()
{
var books = new List<Book> { new Book { ID = 1, BookName = "A" }, new Book { ID = 2, BookName = "B" } };
var x = from d in books
select new
{
ID = d.ID,
BookName = d.BookName
};
string str = JsonConvert.SerializeObject(x.ToList());
Console.WriteLine(str);
}
}
There could be two problems:
A) You are looking at the result from the debugger. To check for this, Put the JsonConvert in a temporary variable (like I did) and look at it with the debugger. Click on the arrow right of the hourglass and select Text Visualizer.
or
B) The calling method is transforming the object again to Json, so escaping everything.
string str = "Your string with slashes";
str = JToken.Parse({your string here}).ToString();
The JSON object is serialized twice.
I solved by:
Declaring the operation contract of the method response format to return JSON.
I changed the method to return an object instead of a string.
The serializing of Jason will be done automatically behind the scenes.
I was getting the same result, but with doubled escape shashes while I was unit testing some json serialization. Looking at my code I realized I am serializing the "expected" json string instead of the actual .net object. So, passing a json string to JsonConvert.SerializeObject(expectedJsonString) will simply escape it once over. This is how I came here, and this is the answer I wrote, when I realized I just did a coding mistake... Did you just realize yours?
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
};