I want to have a class with several nested classes, so that when I create a new parent class, an object of each nested class is created and I can reference the variables within each nested class globally.
Here is my current code:
public class StockChecklist
{
public class qty1p1 { public string tag = "uniqueval23456"; public string value = ""; public string reference = ""; }
public class qty1p2 { public string tag = "uniqueval3736"; public string value = ""; public string reference = ""; }
public class qty2 { public string tag = "uniqueval97357"; public string value = ""; public string reference = ""; }
public class qty3p1 { public string tag = "uniqueval88356"; public string value = ""; public string reference = ""; }
public class qty3p2 { public string tag = "uniqueval62346"; public string value = ""; public string reference = ""; }
public class qty3p3 { public string tag = "uniqueval09876"; public string value = ""; public string reference = ""; }
public class qty3p4 { public string tag = "uniqueval62156"; public string value = ""; public string reference = ""; }
public class qty4 { public string tag = "uniqueval25326"; public string value = ""; public string reference = ""; }
}
then I create a new parent object with:
StockChecklist theCurrentList = new StockChecklist();
but how do access the nested objects 'tag', 'value' and 'reference'? I was hoping for something simple like StockChecklist.qty1p1.tag = 'changedval999999999';
Is something like this possible with C#?
You mixed up definition and declaration. Defining a nested class doesn't create an instance. Also the classes you define looks like they all use the same properties. So, you should define one class and declare multiple instances.
You can fix this with:
C# 6.0
public class Info
{
public string tag { get; set; }
public string value { get; set; }
public string reference { get; set; }
}
public class StockChecklist
{
public Info qty1p1 { get; } = new Info { tag = "uniqueval23456", value = "", reference = "" };
public Info qty1p2 { get; } = new Info { tag = "uniqueval3736", value = "", reference = "" };
public Info qty2 { get; } = new Info { tag = "uniqueval97357", value = "", reference = "" };
public Info qty3p1 { get; } = new Info { tag = "uniqueval88356", value = "", reference = "" };
public Info qty3p2 { get; } = new Info { tag = "uniqueval62346", value = "", reference = "" };
public Info qty3p3 { get; } = new Info { tag = "uniqueval09876", value = "", reference = "" };
public Info qty3p4 { get; } = new Info { tag = "uniqueval62156", value = "", reference = "" };
public Info qty4 { get; } = new Info { tag = "uniqueval25326", value = "", reference = "" };
}
Pre C# 6.0 you have to create the instances in the constructor.
public class StockChecklist
{
public StockChecklist()
{
qty1p1 = new Info { tag = "uniqueval23456", value = "", reference = "" };
qty1p2 = new Info { tag = "uniqueval3736", value = "", reference = "" };
qty2 = new Info { tag = "uniqueval97357", value = "", reference = "" };
qty3p1 = new Info { tag = "uniqueval88356", value = "", reference = "" };
qty3p2 = new Info { tag = "uniqueval62346", value = "", reference = "" };
qty3p3 = new Info { tag = "uniqueval09876", value = "", reference = "" };
qty3p4 = new Info { tag = "uniqueval62156", value = "", reference = "" };
qty4 = new Info { tag = "uniqueval25326", value = "", reference = "" };
}
public Info qty1p1 { get; private set; }
public Info qty1p2 { get; private set; }
public Info qty2 { get; private set; }
public Info qty3p1 { get; private set; }
public Info qty3p2 { get; private set; }
public Info qty3p3 { get; private set; }
public Info qty3p4 { get; private set; }
public Info qty4 { get; private set; }
}
note: Like some comments already noted, declaring 8 instances of the same class within a class could point on 'poor' design. You could create a Dictionary<> for it.
Here is a dictionary version: (bonus)
public class Info
{
public string tag { get; set; }
public string value { get; set; }
public string reference { get; set; }
}
public class StockChecklist
{
private Dictionary<string, Info> _infoDict = new Dictionary<string, Info>();
private void AddToDict(Info info)
{
_infoDict.Add(info.tag, info);
}
public StockChecklist2()
{
AddToDict(new Info { tag = "uniqueval23456", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval3736", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval97357", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval88356", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval62346", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval09876", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval62156", value = "", reference = "" });
AddToDict(new Info { tag = "uniqueval25326", value = "", reference = "" });
}
public bool TryGetByTag(string tag, out Info info)
{
return _infoDict.TryGetValue(tag, out info);
}
public Info this[string tag]
{
get
{
Info info;
if (!_infoDict.TryGetValue(tag, out info))
return null;
return info;
}
}
}
Use it like: (C# 6.0)
StockChecklist stock = new StockChecklist();
Info info;
if (stock.TryGetByTag("uniqueval23456", out info))
{
Trace.WriteLine($"{info.tag} = {info.value}");
}
Or (C# 6.0)
Trace.WriteLine(stock["uniqueval88356"]?.value);
You should do something like this:
public class qty1p1 { public string tag = "uniqueval23456"; public string value = ""; public string reference = ""; }
public class qty1p2 { public string tag = "uniqueval3736"; public string value = ""; public string reference = ""; }
public class qty2 { public string tag = "uniqueval97357"; public string value = ""; public string reference = ""; }
public class qty3p1 { public string tag = "uniqueval88356"; public string value = ""; public string reference = ""; }
public class qty3p2 { public string tag = "uniqueval62346"; public string value = ""; public string reference = ""; }
public class qty3p3 { public string tag = "uniqueval09876"; public string value = ""; public string reference = ""; }
public class qty3p4 { public string tag = "uniqueval62156"; public string value = ""; public string reference = ""; }
public class qty4 { public string tag = "uniqueval25326"; public string value = ""; public string reference = ""; }
public class StockChecklist
{
public qty1p1 _qty1p1;
public qty1p2 _qty1p2;
.
.
.
}
and Then you can use it like:
StockChecklist theCurrentList = new StockChecklist();
theCurrentList._qty1p1.tag = 'changedval999999999';
You can do like this:
public class Parent
{
public class child1 { public string name = "a"; public int Value = 1;}
public class child2 { public string name = "b"; public int Value = 2;}
public class child3 { public string name = "c"; public int Value = 3;}
public class child4 { public string name = "d"; public int Value = 4;}
public class child5 { public string name = "e"; public int Value = 5;}
public child1 c1;
public child2 c2;
public child3 c3;
public child4 c4;
public child5 c5;
public Parent() {
this.c1 = new child1();
this.c2 = new child2();
this.c3 = new child3();
this.c4 = new child4();
this.c5 = new child5();
}
}
class Program
{
static void Main(string[] args)
{
Parent p1 = new Parent();
Console.WriteLine(p1.c1.name);
Console.WriteLine(p1.c2.name);
Console.WriteLine(p1.c3.name);
Console.WriteLine(p1.c4.name);
Console.WriteLine(p1.c5.name);
Console.ReadLine();
}
Related
I want to get the property name and the value from object and pass them to the list.
i dont want to pass one by one property and value to the list like commented in my code. want to use loop and add name and value dynamically
public class ParametersList
{
public string Name { get; set; }
public dynamic Value { get; set; }
}
public class BookVM
{
public string AuthorName{ get; set; }
public string CoverUrl { get; set; }
public int AuthorIds { get; set; }
}
public List<Book> Addgetallbooks(BookVM BookVM)
{
List<ParametersList> obj = new List<ParametersList>();
//List<ParametersList> obj = new List<ParametersList>
//{
// new ParametersList{Name=nameof(BookVM.AuthorIds),Value=BookVM.AuthorIds},
// new ParametersList{Name=nameof(BookVM.AuthorName),Value=BookVM.AuthorName},
// new ParametersList{Name=nameof(BookVM.CoverUrl),Value=BookVM.CoverUrl}
//};
var getdata = _opr.GetBooks1(obj);
return getdata;
}
You need to use reflection, but not sure if you should do it :)
[TestMethod]
public void Foo()
{
var book = new BookVM() { AuthorIds = 1, AuthorName = "some name", CoverUrl = "some cover url" };
var result = GetParameters(book);
result.Should().BeEquivalentTo(new[]
{
new ParametersList { Name = nameof(BookVM.AuthorIds), Value = 1 },
new ParametersList() { Name = nameof(BookVM.AuthorName), Value = "some name" },
new ParametersList { Name = nameof(BookVM.CoverUrl), Value = "some cover url" }
});
}
private static List<ParametersList> GetParameters(BookVM book)
{
return typeof(BookVM).GetProperties().Select(p => new ParametersList
{
Name = p.Name, Value = p.GetValue(book)
}).ToList();
}
I'm trying to realize the listBox with List where i getting some variable.
And when i wonna to add a new "Object" to static List i getting a NullReferenceException
This is my code where i adding a new List
if (EventArgsIn.Message.Chat.Id == MainChatId)
{
if (EventArgsIn.Message.ReplyToMessage != null)
{
var _tempMessage = new listBoxMessage()
{
From = EventArgsIn.Message.From.Username,
FromId = EventArgsIn.Message.From.Id,
MessageId = EventArgsIn.Message.MessageId,
MessageText = EventArgsIn.Message.Text,
MessageIdReply = 0
};
tempMessageMain.Add(_tempMessage);
} else
{
var _tempMessage = new listBoxMessage() {
From = EventArgsIn.Message.From.Username,
FromId = EventArgsIn.Message.From.Id,
MessageId = EventArgsIn.Message.MessageId,
MessageText = EventArgsIn.Message.Text,
MessageIdReply = 0
};
tempMessageMain.Add(_tempMessage);
}
}
And here is my static List
public static List<listBoxMessage> tempMessageMain;
A-a-and my class where i doing Template
public class listBoxMessage
{
public listBoxMessage()
{
}
public string From { get; set; }
public int FromId { get; set; }
public int MessageId { get; set; }
public string MessageText { get; set; }
public int MessageIdReply { get; set; }
}
}
This is test code*
You declared a listbox with next line:
public static List<listBoxMessage> tempMessageMain;
The value of tempMessageMain is still null.
Now you have to create a new instance of tempMessageMain:
public static List<listBoxMessage> tempMessageMain = new List<listBoxMessage>();
I was trying to make a txt file, then rename the extension to .json, I have the encoding step and the WriteAllLines step done, but how do I encode the text?(I have the string needed to write)
Here's the code
string[] lines = { "{", "\"version\": 1,", "\"schema_version\": 2,", "",
$"\"id\": \"{textBox14.Text}\",", "", $"\"title\": \"{textBox7.Text}\",",
$"\"title_localized\": \"{textBox18.Text}\",", "", $"\"artist\": \"{textBox6.Text}\",",
$"\"artist_localized\": \"{textBox8.Text}\",", $"\"artist_source\": \"{textBox9.Text}\",",
$"", $"\"illustrator\": \"{textBox10.Text}\",", $"\"illustrator_source\": \"{textBox11.Text}\",",
$"", $"\"charter\": \"{textBox13.Text}\",", $"", "\"music\": {",
$"\"path\": \"{textBox4.Text}\"", "}", "\"music_preview\": {", $"\"path\": \"{textBox5.Text}\"", "}",
"\"background\": {", $"\"path\": \"{open3.FileName}\"", "}",
"\"charts\": [", "{", "\"type\": \"easy\",", $"\"name\": \"{textBox15.Text}\",",
$"\"difficulty\": {numericUpDown1.Value},", $"\"path\": \"textBox1.Text\"", "},",
"{", "\"type\": \"hard\",", $"\"name\": \"{textBox16.Text}\",", $"\"difficulty\": {numericUpDown2.Value},",
$"\"path\": \"{textBox2.Text}\"", "},", $"]", $"", "}" };
Encoding utf8WithoutBom = new UTF8Encoding(true);
File.WriteAllLines($#"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", lines);
It was supposed to be something like this:
https://cytoid.io/level.json
Short answer:
Change this:
File.WriteAllLines($#"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", lines);
to this:
File.WriteAllLines($#"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", lines, utf8WithoutBom);
Long answer:
You shouldn't be generating JSON like this; you should be using a dedicated serializer. With your current solution, if a user enters an invalid character, your JSON will immediately become invalid. So, as a solution you could use Newtonsoft's JSON.Net. Here is an example:
Class definitions
public class Item
{
public int Version { get; set; }
public int SchemaVersion { get; set; }
public string Id { get; set; }
public string Title { get; set; }
public string TitleLocalized { get; set; }
public string Artist { get; set; }
public string ArtistLocalized { get; set; }
public string ArtistSource { get; set; }
public string Illustrator { get; set; }
public string IllustratorSource { get; set; }
public string Charter { get; set; }
public ItemMusic Music { get; set; }
public ItemMusicPreview MusicPreview { get; set; }
public ItemBackground Background { get; set; }
public List<ItemChart> Charts { get; set; }
}
public class ItemMusic
{
public string Path { get; set; }
}
public class ItemMusicPreview
{
public string Path { get; set; }
}
public class ItemBackground
{
public string Path { get; set; }
}
public class ItemChart
{
public string Type { get; set; }
public string Name { get; set; }
public int Difficulty { get; set; }
public string Path { get; set; }
}
Object initialization and serialization
var item = new Item
{
Version = 1,
SchemaVersion = 2,
Id = textBox14.Text,
Title = textBox7.Text,
TitleLocalized = textBox18.Text,
Artist = textBox6.Text,
ArtistLocalized = textBox8.Text,
ArtistSource = textBox9.Text,
Illustrator = textBox10.Text,
IllustratorSource = textBox11.Text,
Charter = textBox13.Text,
Music = new ItemMusic
{
Path = textBox4.Text
},
MusicPreview = new ItemMusicPreview
{
Path = textBox5.Text
},
Background = new ItemBackground
{
Path = open3.FileName
},
Charts = new List<ItemChart>
{
new ItemChart
{
Type = "easy",
Name = textBox15.Text,
Difficulty = numericUpDown1.Value,
Path = textBox1.Text
},
new ItemChart
{
Type = "hard",
Name = textBox16.Text,
Difficulty = numericUpDown2.Value,
Path = textBox2.Text
}
}
};
var settings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
};
var json = JsonConvert.SerializeObject(item, settings);
File.WriteAllText($#"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", json, new UTF8Encoding(true));
You could also use an anonymous type instead of creating the full class definition, of course:
var item = new {
Version = 1,
SchemaVersion = 2,
Charts = new List<object>
{
new {
Type = "easy"
}
}
}
and then just serialize this.
I have below scenario:
This is my class structure :
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public System.Collections.ObjectModel.Collection<Likes> Likes { get; set; }
}
public class Likes
{
public string Sport { get; set; }
public string Music { get; set; }
public string Food { get; set; }
public string Place { get; set; }
}
When I serialize object of User class then it will generate the below json string :
{"FirstName":"Naresh",
"LastName":"Parmar",
"Likes": [{"Sport":"Cricket",
"Music":"Classic",
"Food":"Gujarati",
"Place":"India"}]
}
I want to generate above json string like below:
{"FirstName":"Naresh",
"LastName":"Parmar",
"Sport":"Cricket",
"Music":"Classic",
"Food":"Gujarati",
"Place":"India"
}
I want the nested properties as primary one.
Any help would be appreciated.
Thanks in advance..
EDIT:
{"FirstName":"Naresh",
"LastName":"Parmar",
"Sport":"Cricket,Chess,Football",
"Music":"Classic",
"Food":"Gujarati",
"Place":"India"
}
It's really bad practice, since the code i'll post bellow doesn't have great maintainability, however if that's what you looking for, you can use this. Another class that have the format that you'd like, and have a method that adds a list of likes to the format you've required. That the class you should serialize to JSON:
class NestedUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Sport { get; set; }
public string Music { get; set; }
public string Food { get; set; }
public string Place { get; set; }
public void AddLikes(System.Collections.ObjectModel.Collection<Likes> likes)
{
foreach (Likes like in likes)
{
Sport += like.Sport + ",";
Music += like.Music + ",";
Food += like.Food + ",";
Place += like.Place + ",";
}
if (Sport != string.Empty)
{
Sport = Sport.Substring(0, Sport.Length - 1);
}
if (Music != string.Empty)
{
Music = Music.Substring(0, Music.Length - 1);
}
if (Food != string.Empty)
{
Food = Food.Substring(0, Food.Length - 1);
}
if (Place != string.Empty)
{
Place = Place.Substring(0, Place.Length - 1);
}
}
}
Since it's not only limited to Likes objects I'd suggest using dynamic objects. So the User class I propose is as follows:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public dynamic Details { get; set; }
public User()
{
Details = new ExpandoObject();
}
public void AddSingleDetail(string key, string value)
{
var dict = this.Details as IDictionary<string, Object>;
if (dict.ContainsKey(key))
{
dict[key] += "," + value;
}
else
{
dict[key] = value;
}
}
public void AddDetails(object detailsObject)
{
var type = detailsObject.GetType();
foreach (var prop in type.GetProperties())
{
AddSingleDetail(prop.Name, prop.GetValue(detailsObject).ToString());
}
}
}
You can use it for adding single proerpties or adding an object as a whole. I used reflection to get all the property name and values and add them to the user details.
Sample usage:
static void Main(string[] args)
{
var user1 = new User() { FirstName = "Homer", LastName = "Simpson" };
user1.AddSingleDetail("Sport", "Bowling");
user1.AddSingleDetail("Sport", "Sleeping");
user1.AddSingleDetail("Food", "Donut");
user1.AddSingleDetail("Music", "Rock");
string flattenedHomer1 = ConvertUserToFlattenedJson(user1);
var user2 = new User() { FirstName = "Homer", LastName = "Simpson" };
var likes1 = new Likes() { Food = "Donut", Music = "Rock", Place = "Springfield", Sport = "Bowling" };
var likes2 = new Likes() { Food = "Steaks", Music = "Metal", Place = "Evergreen Terrace", Sport = "Sleeping" };
var proStuff = new ProfessionalStuff() { Title = "Boss" };
user2.AddDetails(likes1);
user2.AddDetails(likes2);
user2.AddDetails(proStuff);
string flattenedHomer2 = ConvertUserToFlattenedJson(user2);
}
And the method performing the JSON conversion is:
public static string ConvertUserToFlattenedJson(User u)
{
dynamic flatUser = new ExpandoObject();
flatUser.FirstName = u.FirstName;
flatUser.LastName = u.LastName;
var dict = u.Details as IDictionary<string, Object>;
foreach (var like in dict)
{
((IDictionary<string, Object>)flatUser)[like.Key] = like.Value;
}
string json = Newtonsoft.Json.JsonConvert.SerializeObject(flatUser);
return json;
}
In my sample above user2 is converted to the following JSON string which I believe is what you are looking for:
{
"FirstName": "Homer",
"LastName": "Simpson",
"Sport": "Bowling,Sleeping",
"Music": "Rock,Metal",
"Food": "Donut,Steaks",
"Place": "Springfield,Evergreen Terrace",
"Title": "Boss"
}
While concatenating strings you can check for null or duplicate values. I didn't handle that part.
For the sake of completeness, here's the ProfessionalStuff class I made up:
public class ProfessionalStuff
{
public string Title { get; set; }
}
Hope this helps.
I have been looking at this: http://code.msdn.microsoft.com/wpapps/Custom-LongList-Selector-bf8cb9ad and trying to incorporate into my app. However, its a little confusing since my data is loaded differently. Right now, I have two errors The best overloaded method match for CustomKeyGroup<.ViewModels.SoundData>.GetSoundGroups(System.Collections.Generic.List<.ViewModels.SoundData>)' has some invalid arguments
Argument 1: cannot convert from 'string' to 'System.Collections.Generic.List'
The error is at 'CustomKeyGroup.GetSoundGroups(mvm.Items);' from the mainpage.cs. I know the items is an issue. If you look at the link, they load the data differently w/ listmovie.add.
I know something is screwed up big time but since my data is loaded different, im struggling to get it working correctly.
Id like to have custom jumplist w/ headers by Groups (Alpha, Bravo, etc) located in my SoundModel. Here is a portion:
namespace T.ViewModels
{
public class SoundModel: BindableBase
{
public SoundGroup NewAdds { get; set; }
public SoundGroup Software { get; set; }
}
public bool IsDataLoaded { get; set; }
public void LoadData()
{
// Load data into the model
Software = CreateSoftwareGroup();
NewAdds = CreateNewAddsGroup();
IsDataLoaded = true;
}
private SoundGroup CreateNewAddsGroup()
{
SoundGroup data = new SoundGroup();
data.Title = "New";
string basePath = "assets/audio/newadds/";
data.Items.Add(new SoundData
{
Title = "Test1",
FilePath = basePath + "Test.mp3",
Groups = "Alpha"
});
data.Items.Add(new SoundData
{
Title = "Test2",
FilePath = basePath + "Test2.mp3",
Groups="Bravo"
});
data.Items.Add(new SoundData
{
Title = "Test3",
FilePath = basePath + "Test3.mp3",
Groups= "Zulu"
});
private SoundGroup CreateSoftwareGroup()
{
SoundGroup data = new SoundGroup();
data.Title = "Software";
string basePath = "assets/audio/Software/";
data.Items.Add(new SoundData
{
Title = "Test1",
FilePath = basePath + "Test.mp3",
Groups = "Alpha"
});
data.Items.Add(new SoundData
{
Title = "Test2",
FilePath = basePath + "Test2.mp3",
Groups="Bravo"
});
data.Items.Add(new SoundData
{
Title = "Test3",
FilePath = basePath + "Test3.mp3",
Groups= "Zulu"
});
Here is the relevant mainpage.cs:
SoundData mvm = new SoundData();
this.LongList.ItemsSource = CustomKeyGroup<SoundData>.GetSoundGroups(mvm.Items);
SoundGroup:
{
public class SoundGroup
{
public SoundGroup()
{
Items = new List<SoundData>();
}
public List<SoundData> Items { get; set; }
public string Title { get; set; }
public string Groups { get; set; }
}
}
SoundData :
{
public class SoundData : ViewModelBase
{
public string Title { get; set; }
public string FilePath { get; set; }
public string Items { get; set; }
public string Groups { get; set; }
public RelayCommand<string> SaveSoundAsRingtone { get; set; }
private void ExecuteSaveSoundAsRingtone(string soundPath)
{
App.Current.RootVisual.Dispatcher.BeginInvoke(() =>
{
SaveRingtoneTask task = new SaveRingtoneTask();
task.Source = new Uri("appdata:/" + this.FilePath);
task.DisplayName = this.Title;
task.Show();
}
);
}
public SoundData()
{
SaveSoundAsRingtone = new RelayCommand<string>(ExecuteSaveSoundAsRingtone);
}
}
}
So far from I what can see you should be calling the function as below
SoundModel svm = new SoundModel();
svm.LoadData();
this.LongList.ItemsSource = CustomKeyGroup<SoundData>.GetSoundGroups(svm.Software.Items);
or
this.LongList.ItemsSource = CustomKeyGroup<SoundData>.GetSoundGroups(svm.NewAdds.Items);
the reason is that you need to pass a Generic.List<.ViewModels.SoundData> in method GetSoundGroups and the list is contained in SoundGroup class. Since your data loaded is within SoundModel class so I could probably think of the above implementation only.