{get;set;} for arrayList in c# WindowsForms - c#

Is there any solution to use set and get for arraylist ?
I want to put all of my arraylists in one class but then i need them to fill a bidimensional array to use them. (1 list=1 column)
I want to put this
ArrayList listanume = new ArrayList();
In this :
class Beneficiar
{}
And use it to fill an bidimensional array like
listanume -> a[i,0]
I really don't know how to say it right, but this is the idea...

You should do something like that
class Program
{
public static void Main(string[] args)
{
List<Account> accounts = new List<Account>();
Account a1 = new Account { Name = "Peter", Password = "lalala", Mail = "mail#yahoo.com", TotalSold = 100M };
accounts.Add(a1);
}
}
public class Account
{
public string Name { get; set; }
public string Password { get; set; }
public string Mail { get; set; }
public decimal TotalSold { get; set; }
}
To access any account by some field you can do this
string searchNameString = "Peter";
var foundAccount = accounts.FirstOrDefault(x => x.Name == searchNameString);
if (foundAccount != null)
{
//Code which uses found account
}
//Here you will get all accounts with total sold > 1000. You can then iterate over them with for or foreach
var foundAccountsByTotalSold = accounts.Where(x => x.TotalSold > 1000);

Related

String StartsWith Order

I have a CSV File with Raw Data which I'm trying to match with multiple files, while sorting I need to match account codes to their accounts.
I'm using a List of Account and using StartsWith to try and match:
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var accounts = new List<Account> {
new Account {
Id = 9,
Code = "5-4",
Name = "Software",
},
new Account {
Id = 10,
Code = "5-4010",
Name = "Hardware"
}
};
var hardwareAccount = accounts.FirstOrDefault(x => "5-4010".StartsWith(x.Code));
Console.WriteLine(hardwareAccount.Name); // Prints Software - Should be Hardware
var softwareAccount = accounts.FirstOrDefault(x => "5-4020".StartsWith(x.Code));
Console.WriteLine(softwareAccount.Name); // Prints Software - Correct
}
}
public class Account {
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
They are obviously matching the first Account, is there a way to make it match in order?
Updated Solution:
Thanks #SirRufo
class Program
{
static void Main(string[] args)
{
var accounts = new List<Account>
{
new Account
{
Id = 9,
Code = "5-4",
Name = "Software",
},
new Account
{
Id = 10,
Code = "5-4010",
Name = "Hardware"
}
}.OrderBy(x => x.Code.Length);
var hardwareAccount = accounts.LastOrDefault(x => "5-4010".StartsWith(x.Code));
Console.WriteLine(hardwareAccount.Name);
var softwareAccount = accounts.LastOrDefault(x => "5-4020".StartsWith(x.Code));
Console.WriteLine(softwareAccount.Name);
Console.ReadKey();
}
}
public class Account
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
You have to order all matches by the code length
accounts
.Where(x => "5-4010".StartsWith(x.Code))
.OrderBy(x => x.Code.Length)
.LastOrDefault();

CSV file has different rows

I have a csv file that looks like this:
M;2017.12.01 17:04;1;example#example.com
T;1;K001;2
T;1;N001;1
M;2017.11.01 15:56;2;example#example.com
T;2;P001;2
T;2;P001;1
My problem is that I have to read this file into a List<> and be able to navigate in it with indexes but the different types of rows after the long ones are confusing me.
class Order
{
public string Type { get; set; }
public DateTime Date { get; set; }
public string OrderID { get; set; }
public string Email { get; set; }
public string ItemNumber { get; set; }
public int Quantity { get; set; }
public Order(string[] ordered , string[] items)
{
Type = ordered[0];
Date = DateTime.Parse(ordered[1]);
OrderID = ordered[2];
Email = ordered[3];
Type = items[0];
OrderID = items[1];
ItemNumber = items[2];
Quantity = int.Parse(items[3]);
}
}
class Program
{
static List<Order> orders = new List<Order>();
static void Main(string[] args)
{
Reading();
}
private static void Reading()
{
using (System.IO.StreamReader reader = new System.IO.StreamReader("orders.csv"))
{
while (!reader.EndOfStream)
{
orders.Add(new Order(reader.ReadLine().Split(';') , reader.ReadLine().Split(';')));
}
}
}
}
You can try to identify the line before creating it.
Than you can create two different methods to initialize your order.
while (!reader.EndOfStream)
{
var values = reader.ReadLine().Split(';');
if(DateTime.TryParse(values.Skip(1).First(), out var date)) {
orders.Add(Order.FromOrderWithDate(values));
}
else
orders.Last().Items.Add(Item.FromOrderWithEmail(values));
}
The two methods will be something like
public static Order FromRow(string[] ordered) =>
new Order {
Type = ordered[0],
Date = DateTime.Parse(ordered[1]),
OrderID = ordered[2],
Email = ordered[3],
Items = new List<Item>();
};
public static Item FromRow(string[] items) =>
new Item {
Type = items[0],
OrderID = items[1],
ItemNumber = items[2],
Quantity = int.Parse(items[3])
};
And finally two different class, one for order and one for item, the Order should contain a list for the items.
Try something like:
List<Customer> customers = new List<Customer>();
Customer lastCustomer = null;
foreach(var line in File.ReadLines("orders.csv"))
{
var values = line.Split(';');
if (values[0]=="M")
{
lastCustomer = new Customer(values);
customes.Add(lastCustomer);
}
else if (values[0]=="T" && lastCustomer != null)
{
lastCustomer.AddOrder(values);
}
}
(you'll need to write a Customer class that can construct its self from an array of strings, plus has a method for adding new Order objects to its own list of orders, again constructing them from an array)

Casting List Type at Runtime C# Reflection

I've been working on using reflection but its very new to me still. So the line below works. It returns a list of DataBlockOne
var endResult =(List<DataBlockOne>)allData.GetType()
.GetProperty("One")
.GetValue(allData);
But I don't know myType until run time. So my thoughts were the below code to get the type from the object returned and cast that type as a list of DataBlockOne.
List<DataBlockOne> one = new List<DataBlockOne>();
one.Add(new DataBlockOne { id = 1 });
List<DataBlockTwo> two = new List<DataBlockTwo>();
two.Add(new DataBlockTwo { id = 2 });
AllData allData = new AllData
{
One = one,
Two = two
};
var result = allData.GetType().GetProperty("One").GetValue(allData);
Type thisType = result.GetType().GetGenericArguments().Single();
Note I don't know the list type below. I just used DataBlockOne as an example
var endResult =(List<DataBlockOne>)allData.GetType() // this could be List<DataBlockTwo> as well as List<DataBlockOne>
.GetProperty("One")
.GetValue(allData);
I need to cast so I can search the list later (this will error if you don't cast the returned object)
if (endResult.Count > 0)
{
var search = endResult.Where(whereExpression);
}
I'm confusing the class Type and the type used in list. Can someone point me in the right direction to get a type at run time and set that as my type for a list?
Class definition:
public class AllData
{
public List<DataBlockOne> One { get; set; }
public List<DataBlockTwo> Two { get; set; }
}
public class DataBlockOne
{
public int id { get; set; }
}
public class DataBlockTwo
{
public int id { get; set; }
}
You might need something like this:
var endResult = Convert.ChangeType(allData.GetType().GetProperty("One").GetValue(allData), allData.GetType());
Just guessing, didn't work in C# since 2013, please don't shoot :)
You probably want something like this:
static void Main(string[] args)
{
var one = new List<DataBlockBase>();
one.Add(new DataBlockOne { Id = 1, CustomPropertyDataBlockOne = 314 });
var two = new List<DataBlockBase>();
two.Add(new DataBlockTwo { Id = 2, CustomPropertyDatablockTwo = long.MaxValue });
AllData allData = new AllData
{
One = one,
Two = two
};
#region Access Base Class Properties
var result = (DataBlockBase)allData.GetType().GetProperty("One").GetValue(allData);
var oneId = result.Id;
#endregion
#region Switch Into Custom Class Properties
if (result is DataBlockTwo)
{
var thisId = result.Id;
var thisCustomPropertyTwo = ((DataBlockTwo)result).CustomPropertyDatablockTwo;
}
if (result is DataBlockOne)
{
var thisId = result.Id;
var thisCustomPropertyOne = ((DataBlockOne)result).CustomPropertyDataBlockOne;
}
#endregion
Console.Read();
}
public class AllData
{
public List<DataBlockBase> One { get; set; }
public List<DataBlockBase> Two { get; set; }
}
public class DataBlockOne : DataBlockBase
{
public int CustomPropertyDataBlockOne { get; set; }
}
public class DataBlockTwo : DataBlockBase
{
public long CustomPropertyDatablockTwo { get; set; }
}
public abstract class DataBlockBase
{
public int Id { get; set; }
}

C# Initialize Class with a List<T> property

I need some help on how to initialize the below object with some sample values in the Main method to perform some action.
Since I am new to C# please guide me to where can i get this information
class MobOwner
{
public string Name { get; set; }
public List<string> Mobiles { get; set; }
}
Simply initialize it within your constrcutor:
class MobOwner
{
public string Name { get; set; }
public List<string> Mobiles { get; set; }
public MobOwner() {
this.Mobiles = new List<string>();
}
}
You can also define a constructor that direclty puts the right values into your list:
class MobOwner
{
public string Name { get; set; }
public List<string> Mobiles { get; set; }
public MobOwner(IEnumerable<string> values) {
this.Mobiles = values.ToList();
}
}
Which you can than call like new MobOwner(new[] { "Mario", "Hans", "Bernd" })
First of all, I doubt if you really want set; in the Mobiles property:
typically we add/update/remove items in the list, but not assign the list as whole
MobOwner sample = new MobOwner(...);
sample.MobOwner.Add("123");
sample.MobOwner.Add("456");
sample.MobOwner.RemoveAt(1);
sample.MobOwner[0] = "789";
sample.MobOwner = null; // we, usually, don't want such code
The implementation can be
class MobOwner {
public string Name { get; set; }
public List<string> Mobiles { get; } = new List<string>();
public MobOwner(string name, IEnumerable<string> mobiles): base() {
if (null == name)
throw new ArgumentNullException("name");
if (null == mobiles)
throw new ArgumentNullException("mobiles");
Name = name;
Mobiles.AddRange(mobiles);
}
}
you can make and instance and set the variable
var owner = new MobOwner();
owner.Mobiles = new List<string>{"first", "second"};
or like so
var owner = new MobOwner {Mobiles = new List<string> {"first", "second"}};
recommanded way is to use a contructor and make the set properties private
class MobOwner
{
public string Name { get; private set; }
public List<string> Mobiles { get; private set; }
// constructor
public MobOwner(string name, List<string> mobiles)
{
Name = name;
Mobiles = mobiles;
}
}
var mobOwner = new MobOwner()
{
Name = "name";
Mobiles = new List<string>()
{
"mob1",
"mob2",
"mob3"
};
};
This creates one MobOwner object containing a list with one item
MobOwner item = new MobOwner()
{
Name = "foo",
Mobiles = new List<string>() { "bar" }
};
Another way is to add a constructor to simplify instanciation
class MobOwner
{
public string Name { get; set; }
public List<string> Mobiles { get; set; }
public MobOwner(string Name, params string[] Mobiles)
{
this.Name = Name;
this.Mobiles = new List<string>(Mobiles);
}
}
usage:
MobOwner item2 = new MobOwner("foo", "bar", "bar");
If I'm getting your purpose correctly you want to initialize these values in the "Main" method.
Constructor is a good way to initialize your properties with default values whenever you create an instance of your class.
But if you want to initialize them in another place make an instance of your class and then you can give values to its public members. like this:
MobOwner mobOwner = new MobOwner();
mobOwner.Name = "Jimmy";
mobOwner.Mobiles = new List<string>{119, 011};
or in a more modern way you can change the syntax like this(although they are the same):
MobOwner mobOwner = new(){
Name = "Jimmy",
Mobiles = new List<string>{119, 011}
};

Can I put a conditional check on a string to see if it ends in "00" inside a LINQ expression?

I am trying to populate an Objective and ObjectiveDetail objects. Here are the classes I have:
partial class Objective
{
public Objective() {
this.ObjectiveDetails = new List<ObjectiveDetail>();
}
public int ObjectiveId { get; set; }
public string Name { get; set; }
public string Text { get; set; }
public virtual ICollection<ObjectiveDetail> ObjectiveDetails { get; set; }
}
public partial class ObjectiveDetail
{
public int ObjectiveDetailId { get; set; }
public int ObjectiveId { get; set; }
public string Text { get; set; }
public virtual Objective Objective { get; set; }
}
I'm currently populating the only the Objective object from this call:
var objectiveData = GetContent.GetType5();
var objectives = objectiveData.Select(o => new Objective {
Name = o.Name,
Text = o.Text}
);
The data looks like this:
Name Text
0600 header 1
0601 detail abc
0602 detail def
0603 detail ghi
0700 header 2
0701 detail xyz
Is there a way I could modify my LINQ so that only the data where the name field contents end in "00" goes into the Objective object (as it does now) and when the data where the name field contents end in "01" then it creates a new ObjectiveDetail object with "detail abc" etc going into the text field.
This is a picture of what the end result should look like:
A collection of Objectives
new Objective { name = "header 1",
ObjectiveDetails = A collection of ObjectiveDetails
name = "detail abc"
name = "detail def" etc.
Sure you can do that, using [string.EndsWith] method like:1
.Where(r=> r.Name.EndsWith("00"))
Modify your query as:
var objectives = objectiveData
.Where(r => r.Name.EndsWith("00"))
.Select(o => new Objective {
Name = o.Name,
Text = o.Text}
);
It's somewhat unclear what you are asking, but you can put complex logic inside the Select() if you need to:
var objectives = objectiveData.Select(o =>
{
var result = new Objective
{
Name = o.Name,
Text = o.Text
};
if (o.Name != null && o.Name.EndsWith("01"))
{
result.ObjectiveDetails.Add
(
new ObjectiveDetail
{
ObjectiveDetailId = o.ObjectiveId,
Name = o.Name,
Text = o.Text,
Objective = result
}
);
}
return result;
});
(Note that I'm guessing at what you need; you will need to correct the logic to do what you really want.)
Looks like you want to do some sort of conditional mapping. I like Matthew Watson's answer, but it's a bit unclear why he's always creating an Objective instance every time. Here's some LINQ-less code which I believe is more readable, and maps the way I think you'd want:
public class Mapper
{
public List<Objective> Objectives = new List<Objective>();
public class Objective
{
public int ObjectiveId { get; set; }
public string Name { get; set; }
public string Text { get; set; }
public ICollection<ObjectiveDetail> ObjectiveDetails { get; set; }
public Objective()
{
ObjectiveDetails = new List<ObjectiveDetail>();
}
}
public class ObjectiveDetail
{
public int ObjectiveDetailId { get; set; }
public int ObjectiveId { get; set; }
public string Text { get; set; }
public virtual Objective Objective { get; set; }
}
public void Assign()
{
var objectiveData = new[] // Hard-coded test data. We don't know what the type of each item in this list is, so I use an anonymous type
{
new {Name = "0600", Text = "Header 06"},
new {Name = "0601", Text = "06 Detail 01"},
new {Name = "0602", Text = "06 Detail 02"},
new {Name = "0603", Text = "06 Detail 03"},
new {Name = "0700", Text = "Header 07"},
new {Name = "0701", Text = "07 Detail 01"},
new {Name = "0702", Text = "07 Detail 02"}
};
// Create Objectives first
var id = 1;
foreach (var item in objectiveData.Where(i => i.Name.EndsWith("00")))
{
Objectives.Add(new Objective { ObjectiveId = id, Name = item.Name, Text = item.Text });
id++;
}
// Create ObjectiveDetails
id = 1;
foreach (var item in objectiveData.Where(i => !i.Name.EndsWith("00")))
{
var itemLocal = item;
var matchingObjective = Objectives.FirstOrDefault(o => o.Name.StartsWith(itemLocal.Name.Substring(0, 2)));
var objectiveDetail = new ObjectiveDetail
{
ObjectiveDetailId = id,
Text = item.Text,
ObjectiveId = matchingObjective != null ? matchingObjective.ObjectiveId : 0,
Objective = matchingObjective
};
if (matchingObjective != null)
{
matchingObjective.ObjectiveDetails.Add(objectiveDetail);
}
id++;
}
// At the end of this method you should have a list of Objectives, each with their ObjectiveDetails children
}
}
Output:
Hope this helps.

Categories