-2

I'm trying to perform data validation (null checking) on my data before database insertion. I simply want to do a foreach loop over my DB model class like so:

foreach (var item in Insert)
{
    if (item.value == null)
    // do something
}

I've tried a few variations of this and this but I just can't seem to get what I want. Here's what I have so far. In Main.cs

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                var i = 0;
                var Insert = new MyItems();
                foreach (var item in Insert)
                {
                    i++;
                    Debug.WriteLine(i + ": " + item);
                    if (item.value == null)
                    // do something
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

in Model.cs

    public class MyItems : IEnumerable<MyItems>
    {
        List<MyItems> items = new List<MyItems>();

            public IEnumerator<MyItems> GetEnumerator()
        {
            foreach (var item in items)
                yield return item;
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public string HandleUid { get; set; }
        public string TestSpin { get; set; }
        public string PartNumber { get; set; }
        public string LotNumber { get; set; }
        public string MachineName { get; set; }
// plus more items
     }

I've done it this way too which yields the same results.

    public class MyItemList
    {

    }

    public class MyItems : IEnumerable<MyItemList>
    {

        List<MyItemList> items = new List<MyItemList>();

        public IEnumerator<MyItemList> GetEnumerator()
        {
            return items.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public string HandleUid { get; set; }
        public string TestSpin { get; set; }
        public string PartNumber { get; set; }
        public string LotNumber { get; set; }
        public string MachineName { get; set; }
//...

This is just a test program. In my real app, Insert will be populated. When I run this, Insert contains each element but if I step into the foreach loop in the MyItems class, the count is zero, which I sort of understand, but why then does Insert contain an item list? I feel like I keep getting really close to the solution but can't finish the last mile.

So instead of having to do this for many items:

if (Myitems.HandleUid.Value === null)
//do something
if (Myitems.TestSpin.Value === null)
//do something
if (Myitems.PartNumber.Value === null)
//do something
if (Myitems.LotNumber.Value === null)
//do something
if (Myitems.MachineName.Value === null)
//do something
etc...

I want to do this instead:

foreach (var item in Myitems)
{
if (item.value == null)
// do something
}

So I'm trying to add iteration to my custom class.

EE_Kraig
  • 93
  • 1
  • 9
  • 1
    I'm confused by your model class. Why does `MyItems` contain a `List`? Is it meant to be a recursive structure? – John Wu Mar 15 '21 at 19:30
  • Not necessarily. I'm asking for some guidance and maybe that is the wrong way to go about things! – EE_Kraig Mar 15 '21 at 19:59
  • 2
    I can't guide you because I cannot tell what you are trying to accomplish. You say you're trying to check your models for nulls but there isn't even a null check anywhere in your code. – John Wu Mar 15 '21 at 20:27
  • Maybe I should have added that line in my code for clarity but in the foreach in Form1_Load is where that would happen. I mean for now I'd just like to get that foreach to work. – EE_Kraig Mar 15 '21 at 20:32
  • 1
    You have to understand, OP, when you say "get that foreach to work" I haven't the faintest clue what "work" means. It doesn't help that your example is a `MyItem` which is completely ambiguous. Are you trying to iterate over records, properties, or something else? – John Wu Mar 15 '21 at 20:41
  • Not clear what are you asking. -1 – Al Kepp Mar 16 '21 at 00:44
  • Sorry, was trying to be clear. Here MyItems is just the name of my custom class. I added some info to my question to help clarify. – EE_Kraig Mar 16 '21 at 13:35
  • 1
    So basically you want to check each **property** on your class to make sure that it's not null, and you want to do it via **foreach** rather than listing them out individually? You're looking for reflection, but I'd recommend against going that route as a beginner. List them out individually and move on. – zimdanen Mar 16 '21 at 14:08
  • You can also look into data annotations. – zimdanen Mar 16 '21 at 14:10

1 Answers1

1

One way would be to use reflection:

void Main()
{
    var item = new MyItem() 
    {
        PartNumber = "1",
        LotNumber = "2"
    };
    
    var properties = typeof(MyItem).GetProperties(BindingFlags.Instance | BindingFlags.Public).Select(x => (Value: x.GetValue(item), Name: x.Name));
    foreach (var p in properties)
    {
        if(p.Value == null)
            Console.WriteLine($"Property {p.Name} is null");
    }
}

public class MyItem
{
    public string HandleUid { get; set; }
    public string TestSpin { get; set; }
    public string PartNumber { get; set; }
    public string LotNumber { get; set; }
    public string MachineName { get; set; }
}
Magnus
  • 45,362
  • 8
  • 80
  • 118
  • Thank you! I actually use reflection in my app for something else but I got stuck on the idea of adding IEnumerable. Does exactly what I need! – EE_Kraig Mar 16 '21 at 16:34