I'm cleaning up my code trying to short in some things
Now I've stumbled across:
ImageList.Add(test.Properties.Resources.test1);
ImageList.Add(test.Properties.Resources.test2);
ImageList.Add(test.Properties.Resources.test3);
ImageList.Add(test.Properties.Resources.test4);
ImageList.Add(test.Properties.Resources.test5);
(There are 15 of these)
Was wondering if this could be shortened with a for loop
Something like:
for(int i=1; i<=15; i++)
ImageList.Add(test.Properties.Resources.test +i);
Now ofcourse this won't work but I have no clue how to do this (if even possible)
You can iterate over resources via this code
using System.Collections;
using System.Globalization;
using System.Resources;
...
ResourceSet resourceSet = MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key;
object resource = entry.Value;
}
You can use reflection, to get the values:
public class Something
{
public int Test1 { get; set; }
public int Test2 { get; set; }
public int Test3 { get; set; }
public int Test4 { get; set; }
}
var thing = new Something();
var imageProperties = typeof(Something)
.GetProperties()
.Where(p => p.Name.StartsWith("Test"));
var imagesToAdd = imageProperties
.Select(property => property.GetValue(thing))
.ToList();
You could define a property of type IEnumerable<Image> in the class of Resources object
public IEnumerable<Image> Images
{
get
{
yield return test1;
yield return test2;
yield return test3;
yield return test4;
yield return test5;
...
}
}
and then use it to fill ImageList
foreach(var image in test.Properties.Resources.Images)
{
ImageList.Add(image);
}
I just found out that there is a library for evaluating C# expression called Flee. Apparently you can use it to evaluate C# code so that you can loop over variable names, just like JavaScript, but the need for it most likely means a design flaw.
http://flee.codeplex.com/
Related
I have an object like this:
public class Filters {
public int var1 = 1,
var2 = 2,
var3 = 3;
}
I declare this object here:
Filters filter1 = new Filters();
And I want to access var1, var2, and var3 in a loop and do something with it. i.e.:
foreach (var prop in filter1.props) {
Console.WriteLine(filter1[prop] + 3);
}
and the output would be:
4
5
6
I imagine I need to do a foreach loop for each property using
foreach(PropertyInfo p in filter1.GetType().GetProperties()), but I don't know how to 1) loop through props var1, var2, var3, and 2) how to subset the prop from filter1 using the name stored in the variable
If you describe your variable as properties like bellow,
public class Filters
{
public int var1 { get; set; } = 1;
public int var2 { get; set; } = 2;
public int var3 { get; set; } = 3;
}
You can access these properties with
GetType().GetProperties()
then the main method will give you what you ask for
static void Main(string[] args)
{
Filters filter1 = new Filters();
foreach (var prop in filter1.GetType().GetProperties())
{
Console.WriteLine("{0}={1}", prop.Name, (int)prop.GetValue(filter1, null) + filter1.GetType().GetProperties().Length);
}
Console.ReadKey();
}
Result will be
4
5
6
Thanks to everyone who answered-- a couple hints helped me get there. I just started in C# so I didn't know what fields/props were, so thanks #SeM #John. But with that, and with answers by #Icepickle & #arslanaybars with GetProperties() but for fields instead:
FieldInfo[] fields = typeof(GeneralFilters).GetFields();
for (int i = 0; i < fields.Length; i++)
{
//MANIPULATE HERE
BlankTemplate tempFilter = (BlankTemplate)fields[i].GetValue(filters);
// Ignore this for now. tempFilter.selectedItems;
}
where BlankTemplate is defined here:
public class BlankTemplate
{
public string[] selectedItems;
public bool selectAll = false;
}
And now in tempFilter I have the object that I need to use at every iteration
Thanks!!!
Edit: I realize that this doesn't answer the question of how to subset using the stringified name of the object fields. What I envisioned before is generating array of field names, then looping through and subsetting the data in the fields using the field names, like in javascript:
var fieldNames = Object.keys(filterObject);
for (var i = 0; i < fieldNames.length; i++) {
doSomething( filterObject[fieldNames[i]] );
}
But it seems to be a bit different in C#
An alternative answer to your question could be the following, say you have a class of filters like the following
public class Filter
{
public IDictionary<string, object> Properties { get; } = new Dictionary<string, object>();
}
This would allow you to have a dynamic set of filters, you can assign new properties as a consumer and iterate the existing ones. That seems to fit your current requirements.
As for a real answer, as many in the comments have pointed out, if you want to iterate properties, then you should actually use them. In your sample code, you have provided fields instead.
So your class Filter would probably end up looking like this (note that I think var1...var3 are the most horrible names you can use as I cannot imagine what they might define in the end):
public class Filter
{
public int Var1 { get; set; } = 1;
public int Var2 { get; set; } = 2;
public int Var3 { get; set; } = 3;
}
and then you could have something similar like:
var filter = new Filter();
var filterType = filter.GetType();
var readableProperties = filterType.GetProperties().Where( p => p.GetGetMethod() != null );
foreach (var property in readableProperties)
{
var value = (int)property.GetValue( filter );
Console.WriteLine( $"{property.Name} = {value + 3}" );
}
To ensure that you only select those you actually want, you can ofcourse check the name if it equals to Var1, Var2, Var3 or matches a regex expression, or whatever you like to think of ;)
A sample of the code here, you can find in this dotnetfiddle (though without autoproperties and $)
This question already has answers here:
Variables in a loop
(9 answers)
Closed 2 years ago.
I have the following class:
public class Employees {
public string field1 { get; set; }
public string field2 { get; set; }
public string field3 { get; set; }
public string field4 { get; set; }
}
And i want to change values to all those members.
so i can to something like that:
Employees.field1 = "ghgf";
Employees.field2 = "ghgf";
Employees.field3 = "ghgf";
Employees.field4 = "ghgf";
but it's very ugly. and the amount of members will be 30, so this is not a good way...
I want to use for loop, that run over all the members and dynamic took the relevant field and change the value. for example:
for(int i=1; i<4; i++) {
var field = "field" + i;
Employees.field(the Var!!) = "fgdfd";
}
but in this line:
Employees.field(the Var!!) = "fgdfd";
I have a problem because field is the var that was defined in the for loop.
You can do it the hard (and not correct, IMO) way, using reflection.
But if you have 30 variable like this, change your approach: use a List<string>, or a Dictionary <whateverKey, string> to store all your fields
If you really must do it using reflection, you can do it like so:
var employees = new Employees();
var type = employees.GetType();
for (int i = 1; i <= 4; ++i)
type.GetProperty("field"+i).SetValue(employees, "abcde");
Console.WriteLine(employees.field1); // Prints "abcde"
As other folks have pointed out, using reflection in this way seems a little suspect. It looks like you should be doing it a different way, for example by using a Dictionary<string,string>.
You can do it using reflexion like that:
var myEmployees = new Employees();
var properties = myEmployees.GetType().GetProperties();
foreach (var field in properties)
{
field.SetValue(myEmployees, "NewValue");
}
// Print all field's values
foreach (var item in properties)
{
Console.WriteLine(item.GetValue(myEmployees));
}
Otherwise you can use a list or a dictionary or create a new struct that offre you more flexibility and let you able to control more properties of the field:
struct FieldProperties
{
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
...
}
List<FieldProperties> lst = new List<FieldProperties>();
You can try using Reflection
Type type = typeof(Employees);
PropertyInfo pi = this.GetType().GetProperty();
pi.SetField(this, value);
Here is the MSDN link : https://msdn.microsoft.com/en-us/library/ms173183.aspx
Try this approach (using GetMembers()) to get all the members of a class and loop them.
Employees myEmployees = new Employees();
MemberInfo[] members = myType.GetMembers();
for (int i =0 ; i < members.Length ; i++)
{
// Display name and type of the concerned member.
Console.WriteLine( "'{0}' is a {1}", members[i].Name, members[i].MemberType);
}
Been searching and trying different things but just can't seem to get it working right.
So, here are the basics...
namespace Model
{
[Serializable]
public class SomeMDL : IEnumerable<string>
{
public int ID { get; set; }
public int Volumne { get; set; }
public int Size { get; set; }
}
public IEnumerator<string> GetEnumerator()
{
yield return ID.ToString();
yield return Volume.ToString();
yield return Size.ToString();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Then call the class:
Model.SomeMDL mdl = new Model.SomeMDL();
mdl.ID = 1;
mdl.Volume = 2;
mdl.Size = 2;
string myVar;
foreach (string item in mdl)
{
//myVar = item.GetType().ToString();
//myVar = item.GetEnumerator().GetType().Name.ToString();
//myVar = item.GetEnumerator().GetType().FullName.ToString();
//myVar = item.GetEnumerator().GetType().DeclaringType.FullName.ToString(); //null ref
myVar= item.ToString(); //gets the value
}
What I am looking for is a way not only to bring back the values, which is item.ToString() but I need to know which public int it is reading. Is it ID, Volume, or Size?
Need to bring back a string of the type (ID, Volume, or Size).
Thanks
Unless I'm missed something about your code here, it seems like you're misusing/misunderstanding the basic concept of the IEnumerable interface. IEnumerable is used to represent a group of objects of the same type, which can then be iterated through. All you're doing is just yielding each of the properties within your class - what is the point? If you need any one of the properties, why not just access it normally? What do you imagine you'll gain by allowing yourself and others to blindly iterate through your three properties?
I have several classes that inhabit from this class:
public abstract class Class1
{
private string _protocol;
private static List<Plus> _class1Objects;
public string Protocol
{
get { return _protocol; }
set { _protocol = value; }
}
public static List<Plus> Class1Objects
{
get { return _class1Objects; }
set { _class1Objects = value; }
}
}
And the derive class:
public class Class2 : Plus
{
public bool name;
public int id;
}
public Webmail(string name, int id)
{
if (Class1Objects == null)
Class1Objects = new List<class1>();
.....
Class1Objects.Add(this);
}
And after my list is full of Class1Objects:
for (int i = 0; i < Class1.Class1Objects.Count; i++)
{
if (Class1.Class1Objects[i].GetType() == typeof(Class2))
}
(Class2)Class1.Class1Objects[i].
}
}
Here after (Class2)Class1.Class1Objects[i]. i cannot see my Class2 memners
You need one additional paranthese:
((Class2)Class1.Class1Objects[i]).
At the moment it is read as the following:
(Class2)(Class1.Class1Objects[i].) //<= at the '.' it is still a class1
BUT as David said in his comment: If all are of type Class2 it should be a collection of that type and if not you should check the type, altogether with foreach:
foreach(var item in Class1.Class1Objects)
{
if(item is Class2)
((Class2)Class1.Class1Objects[i]).
}
It would be cleaner to use as:
for (int i = 0; i < Class1.Class1Objects.Count; i++)
{
var c2 = Class1.Class1Objects[i] as Class2;
if (c2!=null)
}
c2.<whatever was meant to come after the .>
}
}
You might also want to consider switching to foreach unless there's a specific reason you want to manually extract each element from the List, e.g. if you're actually storing new values back into the list.
The correct syntax would be:
((Class2)Class1.Class1Objects[i]).name;
Because in your case, when you type something like this:
(Class2)Class1.Class1Objects[i].name;
You try to access the member name of Class1.Class1Objects[i], and only after that you try to cast it to Class2.
Also, the whole loop would be much simpler if you used foreach:
using System.Linq;
foreach(Class2 c in Class1.Class1Objects.OfType<Class2>())
{
Console.WriteLine(c.name); // or whatever you need to do with it
}
I am learning the reflections concepts in c#. I have a class like this
public class pdfClass
{
public List<AttributeProperties> TopA { get; set; }
public List<AttributeProperties> TopB { get; set; }
public List<AttributeProperties> TopC { get; set; }
}
In another class I would like to extract the values from the list. I have stupid ways to do it like
public void ExtractValue (pdfClass incomingpdfClass, string type)
{
switch (type)
{
case "TopA":
foreach (var listitem in incomingPdfClass.TopA)
{...}
breaks;
case "TopB":
foreach (var listitem in incomingPdfClass.TopB)
{...}
breaks;
...
}
}
The operations in the foreach loops are similar. How can I do this in a clear way by using reflections?
public void ExtractValue(pdfClass incomingpdfClass, string type)
{
PropertyInfo pinfo = typeof(pdfClass).GetProperty("Top" + type);
var yourList = pinfo.GetValue(incomingpdfClass);
foreach (var listitem in yourList)
{ ... }
}
This is how you should do this using reflection. However, you should note that my code differs from yours in the fact that you are writing code that isn't clear nor would it compile. AS
public class ExtractValue (pdfClass incomingpdfClass, string type)
is non valid C# syntax if that is supposed to be a function as per my example this will work for you
Or if this is supposed to happen in the Constructor for the class it should look as follows
public class ExtractValue
{
public ExtractValue(pdfClass incomingpdfClass, string type)
{
PropertyInfo pinfo = typeof(pdfClass).GetProperty("Top" + type);
var yourList = pinfo.GetValue(incomingpdfClass);
foreach (var listitem in yourList)
{ ... }
}
}
var property = this.GetType().GetProperty(type);
foreach (var item in (List<AttributeProperties>)property.GetValue(this, null))
{
}
If you have instance of pdfClass you do not need to use reflection for accessing lists.
I would suggest to decouple type from strategy itself by persisting such a dictionary:
IDictionary<string, Func<pdfClass, AttributeProperties, bool>> strategy;
Once add relations like
strategy.Add("TopA", (pdf, item) =>
{
return pdf.TopA.IndexOf(item) >= 0;
});
and use like
string itemType = "TopA";
if (strategy.ContainsKey(itemType) )
{
bool found = strategy[itemType](incommingPdfClass, listItem);
}