C# - Property return a lenght array - c#

I have three class :
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
};
public class count
{
public int number
{
get
{
return 1;
}
set
{
}
}
}
public class myclass
{
public Customer[] Customer { get; set; }
public count number { get; set; }
}
And one instance :
myclass myclass = new myclass()
{
Customer = new Customer[]
{
new Customer()
{
FirstName = "FirstName1",
LastName = "LastName1"
},
new Customer()
{
FirstName = "FirstName2",
LastName = "LastName2"
}
},
number = new count()
};
I want the property count.number returns the number of customer in my array Customer[].
I must have a different class to get the number of elements of my array Customer[]
How to do ?
Th

Your property shouldn't have a setter, it should just return the length of the array dynamically. Something like this:
public class myclass
{
public Customer[] Customer { get; set; }
public int number
{
get { return Customer.Length; }
}
}
Then you don't have to manually set it (or, more importantly, manually keep it synchronized as the array changes).
If you must wrap that integer in a class (which you really shouldn't need to, but whatever), then just return an instance of that class:
public class myclass
{
public Customer[] Customer { get; set; }
public count number
{
get { return new count { number = Customer.Length; } }
}
}
However you structure it (that is, whatever reason you have for wrapping primitive values in classes), the point is that you can get the .Length of an array on the fly without having to manually keep track of it yourself. The array knows how long it is.

Related

How to automatically create a default constructor which sets default values

Is there any way to auto generate a constructor which looks like this:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public User(int id, string name)
{
Id = 0;
Name = "";
}
}
Currently I am creating a constructor like that with the refactoring tool (CTRL + .):
public User(int id, string name)
{
Id = id;
Name = name;
}
and editing each line afterwards which is pretty cumbersome when you have 20 properties per class. Is there a better way to that?
(Maybe to define a code snippet, so that we can somehow read the class properties with reflection and define them as snippet parameters?)
If you have a class with 20 properties, why do you need a constructor with 20 parameters? Maybe have a sense, but I usually create constructors to initialize properties that are relevant, to simplify the code, not to set all properties.
For your class, you can set the default values when you define the property and all constructors will use this values as the default.
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = string.Empty;
// Here you can even omit the constructor
public User()
{
}
}
Another thing that maybe useful is define a constructor with X parameters and reuse this constructor in other constructors with less parameters:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public User()
: this(0, string.Empty)
{
}
public User(int id, string name)
{
Id = id;
Name = name;
}
}
You can replace this(0, string.Empty) for this(default, default) if you want use the default value of each type.
If you need object create with default value for properties. You can code like this:
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = "";
}
Purpose of quick action "generate constructor" make method contructor for assign value to fields or properties. Don't use it in the case of just assigning default values.
do you mean initialize properties? Initializing properties through the code reflection mechanism also requires one-by-one assignments. For private object properties, it is necessary to de-private encapsulation. The operation of initializing properties in c# is generally to initialize object properties or object initializers in the form of constructors. Thank you hope it helps you
class Program
{
static void Main(string[] args)
{
Student student = new Student()
{
age = 25,
name = "java",
sex = "female"
};
}
class Student
{
public int age { get; set; }
public string name { get; set; }
public string sex { get; set; }
public Student()
{
}
public Student(int age, string name,string sex)
{
this.age = age;
this.name = name;
this.sex = sex;
}
}
}

How to use IComparable to compare complex objects

Suppose I have a class with firstName and lastName. And I want to compare the object based on firstName so I wrote a snippet like below:
public class Customer : IComparable<Customer>
{
public string FName { get; set; }
public string LName { get; set; }
public int CompareTo(Customer other)
{
return this.FName.CompareTo(other.FName); .
}
}
Main
List<Customer> listCustomers = new List<Customer>();
listCustomers.Add(customer1);
listCustomers.Add(customer2);
listCustomers.Add(customer3);
listCustomers.Sort();
It works fine but suppose somewhere I also need to compare based on last name. What can I don in the scenario. I mean I can Always write my own custom methods but is there any other way? Just like I did it for FName can I also use Icomparable interface to implement sorting based on LName too.
Question: Can I have two version of CompareTo
I want something like
public class Customer : IComparable<Customer>
{
public string FName { get; set; }
public string LName { get; set; }
public int CompareTo(Customer other)
{
return this.FName.CompareTo(other.FName); .
}
public int CompareTo(Customer other)
{
return this.LName.CompareTo(other.LName); .
}
}
It works fine but suppose somewhere I also need to compare based on last name. What can I don in the scenario.
In that scenario, you can use one of the overloads of Sort. Here is an example that compares in three different ways.
public class Program
{
public static void Main()
{
var customers = new List<Customer>
{
new Customer("a", "c", "b"),
new Customer("b", "a", "c"),
new Customer("c", "b", "a"),
};
// A: uses Customer.CompareTo(...)
customers.Sort();
// B: uses a lambda
customers.Sort((x, y) => x.Last.CompareTo(y.Last));
// C: uses MiddleNameComparer.Compare(...)
customers.Sort(new MiddleNameComparer());
}
}
Here is the Customer class that implements IComparable.
public class Customer : IComparable<Customer>
{
public string First { get; set; }
public string Middle { get; set; }
public string Last { get; set; }
public Customer(string first, string middle, string last)
{
First = first;
Middle = middle;
Last = last;
}
public int CompareTo(Customer p)
{
return this.First.CompareTo(p.First);
}
}
Here is the MiddleNameComparer class that implements IComparer.
public class MiddleNameComparer : IComparer<Customer>
{
public int Compare(Customer x, Customer y)
{
return x.Middle.CompareTo(y.Middle);
}
}

Sending List of objects in c# web service

I have the following two objects:
public class Dog
{
public string Name {get;set;}
public int Age {get;set;}
}
public class Person
{
public string Name {get;set;}
public string City {get;set;}
public string ID {get;set;}
}
Now, in the server side, I build a mix List of Person and Dog, and I would like to return this List to the client via web-service (asmx).
The order is important, and eventually my list will hold more types.
How can I return a list of mixed object in web-service?
Thank you.
I think you should create new class that encapsulate your many classes
public class Dog : MyClass
{
public string Name {get;set;}
public int Age {get;set;}
}
public class Person : MyClass
{
public string Name {get;set;}
public string City {get;set;}
public string ID {get;set;}
}
public class NewClass
{
public enum OBJType {
Dog,Person
} // like a constant for specific object type
public Dog D_Dog { get; set; }
public Person D_Person { get; set; }
public OBJType Type { get; set; }
public int seq { get; set; }
}
Then it should be use like this
//At Server
List<NewClass> newList = new List<NewClass>();
NewClass Item1 = new NewClass();
Item1.D_Dog = new Dog() { Name = "Woof", Age = 3 };
Item1.seq = 1;
Item1.Type = NewClass.OBJType.Dog;
newList.Add(Item1);
NewClass Item2 = new NewClass();
Item2.D_Person = new Person() { Name = "John", City = "TPP" , ID =111 };
Item2.seq = 2;
Item2.Type = NewClass.OBJType.Person;
newList.Add(Item2);
//At Client
List<NewClass> newList = //..get form webservice
foreach (var Item in newList)
{
if (Item.Type == NewClass.OBJType.Dog)
{
// using Item.D_Dog;
}
else {
// using Item.D_Person
}
}
Not a pro at C# so excuse if its not the most efficient.
1st class ie Person.cs
public class Person : MyClass
{
public string Name { get; set; }
public string City { get; set; }
public string ID { get; set; }
}
2nd Class ie Dog.cs
public class Dog : MyClass
{
public string Name { get; set; }
public int Age { get; set; }
}
The inherited class ie MyClass.cs
public class MyClass
{
public string Type { get; set; }
}
Notice I have added a field Type to differentiate between objects in the program consuming the webservice. You can improve this with enums for type.
The Example function to return the data.
public List<MyClass> returnData()
{
List<MyClass> returningdata = new List<MyClass>();
Person pers = new Person();
pers.City = "NELSPRUIT";
pers.Name = "TED";
pers.ID = "5502226585665";
pers.Type = "PERSON";
returningdata.Add(pers);
Dog doggy = new Dog();
doggy.Name = "Tiny";
doggy.Age = 2;
doggy.Type = "DOG";
returningdata.Add(doggy);
return returningdata;
}
Hope this is what you wanted.

How to set list A equal to list B, where on B a property does not exist which does exist on A

I have a C# list which is of type Person. This list needs to be converted into JSON data format. The Person C# class look like this:
public class Person
{
public int ID { get; set; }
public static int PSID = 1;
public string name { get; set; }
public string nameToken { get; set; }
public double DOB { get; set; }
public List<Award> awards { get; set; }
public List<Link> links { get; set; }
public Person()
{
awards = new List<Award>();
links = new List<Link>();
ID = PSID;
PSID++;
}
}
As I am required to convert a C# list of type Person into JSON. I made another Class in C# called PersonJS. It is exactly like the Person C# class the only difference is that I have removed some of the properties that are not required in the JSON front-end. Namely: nameToken, PSID.
public class PersonJS
{
public int ID { get; set; }
public string name { get; set; }
public double DOB { get; set; }
public List<AwardJS> awards { get; set; }
public List<Link> links { get; set; }
}
One of the properties of PersonJS is a List called awards which is of Type AwardJS. A problem occurs below because I try and equal Person.awards List equal to PersonJS.awards List. However, they are of difference types so it is not possible to equal both lists. The reason why I have put them equal to different types is because the JSON data does not need all of the properties that I have used in C#. So I made two classes Award and AwardJS. The only difference is that Award contains a property called filmWebToken whereas AwardJS does not.
public class Award
{
public int filmID { get; set; }
public int categoryID { get; set; }
public string filmWebToken { get; set; }
}
public class AwardJS
{
public int filmID { get; set; }
public int categoryID { get; set; }
}
In my code I iterate over all of the properties in C# list of type Person and I attempt to create a personjs object and add it to a PersonJS C# list. The PersonJS list will go back to the front-end as JSON. However, because the award property in the class PersonJS is different to the award property in Person I get the error "Cannot implicitly convert type AwardJS to Award". The reason I get this error is because PersonJS does not contain filmWebToken which exists in the Person class. I don't want the filmWebToken to be in the PersonJS list as it is not meant to be a property in my JSON data. However, as there are property fields in Person.Award I still want access to: filmID and CategoryID how can I ignore/by-pass the filmWebToken field. This is what I have tried:
List<Person> allPersons = DataRepository.GetAllPersons(); // contains the C# data
List<PersonJS> personjs = new List<PersonJS>(); // empty to start with
foreach (var person in allPersons)
{
foreach (var award in person.awards)
{
personjs.Add(
new PersonJS
{
ID = person.ID,
links = person.links,
name = person.name,
DOB = person.DOB,
awards = person.awards // The types are not equal: Person contains filmWebToken whereas PersonJS does not
});
}
}
Add a method called ToAwardJS in Award:
public AwardJS ToAwardJS() {
return new AwardJS { filmID = this.filmID, categoryID = this.categoryID };
}
Then when you create the PersonJS object, do:
new PersonJS
{
ID = person.ID,
links = person.links,
name = person.name,
DOB = person.DOB,
awards = person.awards.Select(x => x.ToAwardJS()).ToList(),
});
What serializer are you using? Most provide attributes to specify which members to include in the serialization. For example, the DataContractJsonSerializer uses [DataContract] and [DataMember]. I think Json.net uses [JsonIgnore]. There's no need for multiple classes.
void Main()
{
var jsSer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(Person));
var p = new Person {
ID = 1,
name = "John",
DOB = 1234.5,
nameToken = "token"
};
string result = null;
using (var ms = new MemoryStream())
{
jsSer.WriteObject(ms, p);
byte[] json = ms.ToArray();
ms.Close();
result = Encoding.UTF8.GetString(json, 0, json.Length);
}
Console.WriteLine(result);
}
[DataContract]
public class Person
{
//included
[DataMember]
public int ID { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string nameToken { get; set; }
[DataMember]
public double DOB { get; set; }
//ignored
public static int PSID = 1;
public List<string> awards { get; set; }
public List<string> links { get; set; }
public Person()
{
awards = new List<Award>();
links = new List<Link>();
ID = PSID;
PSID++;
}
}
Result:
{"DOB":1234.5,"ID":1,"name":"John","nameToken":"token"}

Match names in list with elements in class

I wonder if there's any way to match the names in a list with the elements in a class:
I have a class:
public class exampleClass
{
public string name { get; set; }
public string value { get; set; }
}
and a List: List<exampleClass> EnfSist
So that's the way the list is made. Now I would like to know how to match or identify the string inside "name" from my list. To match this class:
tbl_sistematicas b = new tbl_sistematicas
{
ap_enf_id_enfermedad = Convert.ToInt32(EnfSist[0].value),
ap_pac_inicio = Convert.ToInt32(EnfSist[1].value),
ap_pac_inicio_periodo = Convert.ToInt32(2].value),
ap_pac_duracion = Convert.ToInt32(EnfSist[3].value),
ap_pac_duracion_periodo = Convert.ToInt32(EnfSist[4].value),
ap_pac_tratamiento = EnfSist[5].value
};
Once being able to match the same names I won't have to specify each index of every element in the list. The elements in the list have the same name as in the table. Not all elements of the class are being used.
I have something like this: tbl_sistematicas bh = EnfSist.FindAll(x => x.name == bh.?????? );
If I understand the question, you can do this using something like automapper or ValueInjector
An example using ValueInjector
void Main()
{
List<exampleClass> EnfSist = new List<exampleClass>();
EnfSist.Add(new exampleClass { name = "ap_enf_id_enfermedad", value = "12" });
EnfSist.Add(new exampleClass { name = "apap_pac_inicio" , value = "34" });
// etc
tbl_sistematicas b = new tbl_sistematicas();
b.InjectFrom<MyInjection>(EnfSist);
}
public class MyInjection : KnownSourceValueInjection<List<exampleClass>>
{
protected override void Inject(List<exampleClass> source, object target)
{
foreach(var entry in source)
{
var property = target.GetProps().GetByName(entry.name, true);
if (property != null)
property.SetValue(target, Convert.ChangeType(entry.value, property.PropertyType));
}
}
}
public class exampleClass
{
public string name { get; set; }
public string value { get; set; }
}
public class tbl_sistematicas
{
public int ap_enf_id_enfermedad { get; set; }
public int apap_pac_inicio { get; set; }
public int ap_pac_inicio_periodo { get; set; }
public int ap_pac_duracion { get; set; }
public int ap_pac_duracion_periodo { get; set; }
public string ap_pac_tratamiento { get; set; }
}
Note, this will throw an exception if the value can not be converted to an int

Categories