I am trying to create a method that increases the family age by one. Passing arguments to method is extremely difficult for me, especially with this problem. I believe there is a better way of doing this, but this is the only way that can come to mind. I am currently having trouble trying to display all 4 of the families age into one label, after their age is increased by one. This is currently what I have:
// Create a method using the increment operator that increates the age of 4 family members by 1
private void TotalAge (int age1/*, int age2, int age3, int age4*/)
{
age1++;
/* age2++;
age3++;
age4++; */
}
private void calculateButton_Click(object sender, EventArgs e)
{
// Variables to hold family member ages
int member1 = 0, member2 = 0, member3 = 0, member4 = 0;
// Conver the ages into a string, using tryparse method
if (int.TryParse(ageTextBox1.Text, out member1))
{
if (int.TryParse(ageTextBox2.Text, out member2))
{
if (int.TryParse(ageTextBox3.Text, out member3))
{
if (int.TryParse(ageTextBox4.Text, out member4))
{
displayAge.Text = Convert.ToString(TotalAge(member1))
}
}
}
}
}
you should create a FamilyMember class that will contain all the properties of a family member (age, name, etc.) then you simply pass a list or an array of family members to a function that will increment in 1 the age of every FamilyMember in the array.
Public class FamilyMember
{
public string Name {private set; get;}
public int Age { private set; get; }
public FamilyMember(string name, int age)
{
Name = name;
Age = age;
}
public void IncrementAge()
{
Age++;
}
}
Public void IncrementAgeOfFamilyMembers(List<FamilyMember> FamilyMembers)
{
foreach (var fmember in FamilyMembers)
fmember.IncrementAge();
}
if you want it to be for exactly 4 family members just change the List<FamilyMember> to FamilyMember[4] (but then you should check for nulls)
Related
I have code as follow:
struct Name
{
private int age;
public int Age
{
get
{
return age;
}
set
{
age = Age;
}
}
public Name(int a)
{
age = a;
}
};
class Program
{
static void Main(string[] args)
{
Name myName = new Name(27);
Console.WriteLine(myName.Age);
myName.Age = 30;
Console.WriteLine(myName.Age);
}
}
As you can see I am trying to change value of Age using my property. But i am getting still the same value which I pass when I am creating a object of struct Name. I know that struct are immutable in C#, but i thought i would bee able to change field in them. I am very confused. Could someone explain me what is going on?
Structs in C# are not immutable by default. To mark a struct immutable, you should use the readonly modifier on the struct. The reason your properties aren't updating is that your syntax is wrong. You should use the value keyword to dereference the value provided to the setter.
public int Age
{
get
{
return age;
}
set
{
age = value; // <-- here
}
}
public EnumA
{
name = 1,
surname = 2
}
public EnumB
{
name = 50,
surname = 60
}
public void myMethod(User u,Enum e)
{
//Enum e can be either EnumA or EnumB
//Do something with the Enum Passed
}
Let's say I have the above code but instead of specifiying the Enum in the method like I'm doing above, I'd like to select the enum which is passed through the method parameter. Is there any way of doing so?
You can do this via reflection, but I'm worried that you don't understand enumerations properly. It kind of looks to me like you are trying to use them as class instances to hold arbitrary data, in which case, you really should be using a real class.
In case I'm wrong, I've included code below to do what you are asking for, but I don't think it will be very useful for you.
void Main()
{
Test(EnumA.First);
Console.WriteLine("-----");
Test(EnumB.B);
}
void Test(Enum theEnum)
{
Type t = theEnum.GetType();
foreach (string element in Enum.GetNames(t))
{
Debug.WriteLine(element + " = " + (int) Enum.Parse(t, element));
}
}
enum EnumA
{
First = 1,
Second = 2
}
enum EnumB
{
A = 1,
B = 2,
C = 3
}
It generates the following output:
First = 1
Second = 2
-----
A = 1
B = 2
C = 3
I think this is more what you are trying to do though:
void Main()
{
Person A = new Person()
{
Name = "John",
Surname = "Doe"
};
Person B = new Person()
{
Name = "Jane",
Surname = "Doe"
};
A.ShowInfo();
Console.WriteLine("----");
B.ShowInfo();
}
class Person
{
public string Name { get; set; }
public string Surname { get; set; }
public void ShowInfo()
{
Debug.WriteLine("Name=" + Name);
Debug.WriteLine("Surname=" + Surname);
}
}
It output the following:
Name=John
Surname=Doe
----
Name=Jane
Surname=Doe
Have you tried the following:
public void myMethod(User u,Enum e)
{
if (e is EnumA)
{
EnumA ea = (EnumA)e;
// Do something with ea
}
else if (e is EnumB)
{
EnumB eb = (EnumB)e;
...
}
}
you have use generic type for this operation.
below code is showing a sample code (as Console app);
class Program
{
static void Main(string[] args)
{
myMethod<EnumA>("deneme", EnumA.name);
}
public enum EnumA
{
name = 1,
surname = 2
}
public enum EnumB
{
name = 50,
surname = 60
}
public static void myMethod<T>(string u, T e)
where T : struct,IConvertible
{
if (typeof(T) == typeof(EnumA))
{
Console.WriteLine("EnumA");
}
else if (typeof(T) == typeof(EnumB))
{
Console.WriteLine("EnumB");
}
Console.ReadLine();
}
}
You could use overloading:
public void myMethod(User u, EnumA e)
{
// Call a function common to both
}
public void myMethod(User u, EnumB e)
{
// Call a function common to both
}
I guess C# 7.3 allows you to do something like:
public void myMethod(User u, TEnum e) where TEnum : Enum
{
//Enum e can be either EnumA or EnumB
//Do something with the Enum Passed
}
I used something like this for a pre-7.3 project and it was a little ugly, but WAY better and more readable than any other way I could find:
public void myMethod(User u, object e)
{
// Test to make sure object type is either EnumA or EnumB
// Call a function common to both
// object e can be either EnumA or EnumB by casting like ((EnumA)e) or ((EnumB)e)
}
This is not how enums behave (or should behave). You're basically creating two different instances of enums. This is why classes exist in C#. Consider creating a class:
public class SomeEnum
{
public int Name;
public int Surname;
private SomeEnum(int name, int surname)
{
Name = name;
Surname = surname;
}
public static SomeEnum EnumA => new SomeEnum(1, 2);
public static SomeEnum EnumB => new SomeEnum(50, 60);
}
And changing your method to this:
public void myMethod(User u, SomeEnum e)
{
// Enum e can be either EnumA or EnumB
// Do something with the Enum passed
}
I changed as least code as possible as I'm not sure what the purpose is of these 'Enums', but this way you'll be able to create as many instances as you want, without your code getting messy with all of these identical Enum specifications.
To use this method with EnumA for example you can call myMethod(user, SomeEnum.EnumA).
This way it's only possible to use the specified enums (EnumA and EnumB). Alternatively, if you want to create enums on-the-fly, the code can be changed to:
public class SomeEnum
{
public int Name;
public int Surname;
public SomeEnum(int name, int surname)
{
Name = name;
Surname = surname;
}
}
This way you can call the method with myMethod(user, new SomeEnum(1, 2)).
I want to add row number in object list.
here's the they i do it now but there must be better way
Profile for mapping
public class VendorEnquiryDM_TO_VM : Profile
{
public VendorEnquiryDM_TO_VM()
{
CreateMap<VENDORENQUIRY, VendorEnquiryVM>();
}
}
public class VendorEnquiryVM_TO_DM : Profile
{
public VendorEnquiryVM_TO_DM()
{
CreateMap<VENDOR_ENQUIRY, VendorEnquiryVM>().ReverseMap();
}
}
Register profile
cfg.AddProfile<VendorEnquiryDM_TO_VM>();
cfg.AddProfile<VendorEnquiryVM_TO_DM>();
This is how I add sno.
alldata = Mapper.Map<IEnumerable<Vendor_EnquiryVM>>(objDAO.getVendorEnquiry());
var _roles = alldata.Select((t, index) => new Vendor_EnquiryVM
{
sno = index + 1,
CONTACT_NO=t.CONTACT_NO,
DATE=t.DATE,
EMAIL=t.EMAIL,
id=t.id,
FIRST_NAME=t.FIRST_NAME,
wer=t.wer,
asdf=t.asdf
});
Due to just one serial no. I need to assign all properties and this is somewhat fraustrating to me for large model, please suggest me better way of doing this.
You can define a static Id and when you create the class, increment it by one
here how your class code should look like
public class Test
{
private static int mId = 0;
public Test()
{
mId = mId +1;
}
public int Id
{
get{ return mId;}
}
}
Here a demo
in order to use the same idea with collections like List, I applied some modifications and here what you can do
public class Test
{
private static int mIndex = 0; // this parameter will be incremented for each new Test
private int mId =0; // this parameter will hold the last incremented value
public Test()
{
mId = ++mIndex; // mIndex++ if you want to start with 0
}
public int Id
{
get{ return mId;}
}
}
Demo with lists
hope this will help you
I am having some trouble in querying an object array using LINQ. I want to retrieve all products that contains the value passed.
My Product class
public class Product
{
public int mProductId;
public string mProductName;
public string mProductColor;
public string mProductSize;
public string mProductStatus;
public string mProductCode;
public int ProductId{ get { return mProductId; }}
public string ProductName { get{return mProductName; }}
public string ProductColor { get{return mProductColor;} }
public string ProductSize { get{return mProductSize;} }
public string ProductStatus { get{return mProductStatus;} }
public string ProductCode {get { return mProductCode; }}
}
public class ProductList
{
public static Product[] mProductList = {
new Product { mProductId = Resource.Drawable.Product1,
mProductName = "Green Lumberjack Cap",
mProductColor = "Color Brown",
mProductSize = "One Size Fits All",
mProductCode= "9780201760439",
mProductStatus= "In Stock"},
new Product { mProductId = Resource.Drawable.Product2,
mProductName = "Square Bar stool",
mProductColor= "Color Brown",
mProductSize = "One Size Fits All",
mProductCode= "9780201760440",
mProductStatus= "In Stock"},
new Product { mProductId = Resource.Drawable.Product3,
mProductName = "Vitra bathroom Tile",
mProductColor= "Color Brown",
mProductSize = "One Size Fits All",
mProductCode= "9780201760539",
mProductStatus= "In Stock"},
};
private Product[] mProducts;
Random mRandom;
public ProductList ()
{
mProducts = mProductList;
}
// Return the number of photos in the photo album:
public int NumPhotos
{
get { return mProducts.Length; }
}
// Indexer (read only) for accessing a photo:
public Product this[int i]
{
get { return mProducts[i]; }
}
// Pick a random photo and swap it with the top:
public int RandomSwap()
{
// Save the photo at the top:
Product tmpProduct = mProducts[0];
// Generate a next random index between 1 and
// Length (noninclusive):
int rnd = mRandom.Next(1, mProducts.Length);
// Exchange top photo with randomly-chosen photo:
mProducts[0] = mProducts[rnd];
mProducts[rnd] = tmpProduct;
// Return the index of which photo was swapped with the top:
return rnd;
}
// Shuffle the order of the photos:
public void Shuffle ()
{
// Use the Fisher-Yates shuffle algorithm:
for (int idx = 0; idx < mProducts.Length; ++idx)
{
// Save the photo at idx:
Product tmpProduct = mProducts[idx];
// Generate a next random index between idx (inclusive) and
// Length (noninclusive):
int rnd = mRandom.Next(idx, mProducts.Length);
// Exchange photo at idx with randomly-chosen (later) photo:
mProducts[idx] = mProducts[rnd];
mProducts[rnd] = tmpProduct;
}
}
}
and my LINQ statement is
var result = from p in nProductList<Product>
where ( p.mProductName.Contains(query) || p.mProductColor.Contains(query))
select p;
I have also declared nProductList in my class as
public ProductList nProductList;
It will be really great to know what am I doing wrong.
Thank you
In order to get the where keyword syntax to work, your ProductList class must have a Where(Func<Product, bool>) method on it. Most lists get this automatically because they implement IEnumerable<>, and the System.Linq namespace has a Where() extension method which matches this signature.
You could make ProductList implement the IEnumerable<Product> interface, or make it extend a class like List<Product> which already implements that interface, or add your own Where() method. However, I'd personally suggest that you just expose mProductList as an IEnumerable<Product> via a public property getter, and change your consuming code to query against that.
The reason why your linq statement does not work is because you did not define where. Imagine the old style linq:
nProductList.Where(p=>p.mProductName.Contains(query) || p.mProductColor.Contains(query)).Select(p=>);
nProductList does not have Where(Func) defined so it does not work.
Normally for your ProductList there are two ways to implement. First way is to inherit from IEnumerable<Product> as ProductList : IEnumerable<Product>;
Second way is to create a member in ProductList and make it public like
public class ProductList
{
public IEnumerable<Product> Products {get; private set;}
...
}
Usually the preferable way between the two above will depends on is there more properties or more methods in your ProductList class. More methods goes to the first way because it's more like an expended method collection of IEnumerable class (like your example), while more properties goes to the seconding way as this is more like another class just having a list in it and something else.
Is it somehow possible for properties to reference each other during the creation of a dynamic object an anonymously-typed object (i.e. inside the object initializer)? My simplified example below needs to reuse the Age property without making a second heavy call to GetAgeFromSomewhere(). Of course it doesn't work. Any suggestion on how to accomplish this?
var profile = new {
Age = GetAgeFromSomewhere(id),
IsLegal = (Age>18)
};
Is something like this possible or not possible with dynamic objects anonymously-typed object initializers?
Unfortunately it's not possible, even with explicitly typed objects. This is because of the way object initializers work. For example:
public class MyClass
{
public int Age = 10;
public bool IsLegal = Age > 18;
}
Yields this compiler error at "IsLegal":
Error 1 A field initializer cannot reference the non-static field,
method, or property 'MyClass.Age' ...
Field initializer can't reference other non-static fields, and since anonymous types don't create static fields, you can't use the value of one field to initialize another. The only way around this, is to declare the variables outside the anonymous type and use them inside the initializer.
int age = GetAgeFromSomewhere(id);
var profile = new {
Age = age,
IsLegal = age > 18
};
Don't complicate thing, keep it simple
//Create a variable
var age = GetAgeFromSomewhere(id);
var profile = new {
Age = age,
IsLegal = age>18
}
What you want is not possible within object intializers. You cannot read properties of the object being initialized. (It does not matter, whether the type is anonymous or not.)
Instead, Create a class
public class Profile
{
public Profile(int id)
{
Age = GetAgeFromSomewhere(id);
}
public int Age { get; private set; }
public int IsLegal { get { return Age > 18; } }
}
Or getting the age the lazy way:
public class Profile
{
private readonly int _id;
public Profile(int id)
{
_id = id;
}
private int? _age;
public int Age {
get {
if (_age == null) {
_age = GetAgeFromSomewhere(_id);
}
return _age.Value;
}
}
public int IsLegal { get { return Age > 18; } }
}
or using the Lazy<T> class (starting with Framework 4.0):
public class Profile
{
public Profile(int id)
{
// C# captures the `id` in a closure.
_lazyAge = new Lazy<int>(
() => GetAgeFromSomewhere(id)
);
}
private Lazy<int> _lazyAge;
public int Age { get { return _lazyAge.Value; } }
public int IsLegal { get { return Age > 18; } }
}
Call it like this
var profile = new Profile(id);
If you don't want to have unnecessary variable, I suggest you use the current object instead :
var profile = new
{
Age = GetAgeFromSomewhere(id),
};
profile.IsLegal = profile.Age > 18;