다음을 통해 공유


C# - Lambda Periodic Table Searcher


Overview

This article is intended to show two programming lessons for beginner programmers. 

First, it shows how to combine object arrays, simple user-defined object classes, properties, and simple code, to create OOP (Object Oriented Programming) applications with Visual Studio. 

Secondly, it shows how to use simple LINQ queries with Lambda functions, to quickly search a user-defined object array.

Arrays in VS can be arrays of primitive types (Integer, Byte, Boolean etc.), but it's possible to create an array of just about any type you can imagine. A user-defined class typically contains Properties and Public or sometimes Private Methods. In the case of the example programs there are two user-defined classes - ElementDetails, which contains (from each element) the AtomicNumber, the Symbol, the Element (name), the [Type] (the Element's group), and finally the Image Property, which actually returns a dynamic Bitmap created on the fly in the Property Getter. The [Type] Property could have been a String representing the name of the group, but it was advantageous to store two Properties related to the Group - the name, and a color. So, the return type of the Type Property is ElementType, which is the second of the core classes used.

LINQ combined with Lambda gives great results from minimal code. It is possible to query the user-defined array on any of the Properties to retrieve either one element or a group of elements.


The searchForm code



      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows.Forms;
      using Lambda_Periodic_Table_Searcher_cs.core;
      using Lambda_Periodic_Table_Searcher_cs.gui;
   
      namespace Lambda_Periodic_Table_Searcher_cs
      {  
                    public partial  class searchForm : Form  
                    {      
   
                        ElementType[] types = {       new  ElementType("Alkali metal", 255, 101, 101),  
                            new ElementType("Alkaline earth metal", 255, 222, 174),  
                            new ElementType("Lanthanide", 255, 188, 253),  
                            new ElementType("Actinide", 255, 150, 201),  
                            new ElementType("Transition metal", 255, 190, 191),  
                            new ElementType("Post-transition metal", 203, 203, 203),  
                            new ElementType("Metalloid", 203, 204, 154),  
                            new ElementType("Polyatomic nonmetal", 159, 255, 196),  
                            new ElementType("Diatomic nonmetal", 230, 255, 148),  
                            new ElementType("Noble gas", 190, 255, 255),  
                            new ElementType("Unknown chemical properties", 231, 231, 231) };  
   
                        ElementDetails[] elements =       new  ElementDetails[118];  
   
                        bool ignore = false;  
   
                        public searchForm()  
                        {      
                            InitializeComponent();      
   
                            string      [] lines = Properties.Resources.elements.Split(      new string[] { Environment.NewLine }, StringSplitOptions.None);  
                            for (int x = 0; x <= 117; x++)  
                            {      
                                elements[x] =       new  ElementDetails(types, lines[x].Split('|'));  
                            }      
                        }      
   
                        private void  NumericUpDown1_ValueChanged(object sender, EventArgs e)  
                        {      
                            updateFields(0, elements.FirstOrDefault(el => el.AtomicNumber() == (      int      )NumericUpDown1.Value));      
                        }      
   
                        private void  TextBox1_TextChanged(object sender, EventArgs e)  
                        {      
                            updateFields(1, elements.FirstOrDefault(el => el.Symbol().Equals(TextBox1.Text)));      
                        }      
   
                        private void  TextBox2_TextChanged(object sender, EventArgs e)  
                        {      
                            updateFields(2, elements.FirstOrDefault(el => el.Element().Equals(TextBox2.Text)));      
                        }      
   
                        private void  Button1_Click(object  sender, EventArgs e)  
                        {      
                            if (Button1.Text != "")  
                            {      
                                ElementDetails[] group = elements.Where(el => el.Group().Name().Equals(Button1.Text)).ToArray();      
                                listForm frm =       new  listForm(Button1.Text, group);  
                                frm.ShowDialog();      
                            }      
                        }      
   
                        private void  updateFields(int  exclude, ElementDetails current)  
                        {      
                            if (ignore)  
                                return      ;      
                            ignore =       true      ;      
                            switch (exclude)  
                            {      
                                case 0:  
                                    if (current != null)  
                                    {      
                                        TextBox1.Text = current.Symbol();      
                                        TextBox2.Text = current.Element();      
                                        Button1.BackColor = current.Group().Color();      
                                        Button1.Text = current.Group().Name();      
                                    }      
                                    else      
                                    {      
                                        clearFields(exclude);      
                                    }      
                                    break      ;      
                                case 1:  
                                    if (current != null)  
                                    {      
                                        NumericUpDown1.Value = current.AtomicNumber();      
                                        TextBox2.Text = current.Element();      
                                        Button1.BackColor = current.Group().Color();      
                                        Button1.Text = current.Group().Name();      
                                    }      
                                    else      
                                    {      
                                        clearFields(exclude);      
                                    }      
                                    break      ;      
                                case 2:  
                                    if (current != null)  
                                    {      
                                        NumericUpDown1.Value = current.AtomicNumber();      
                                        TextBox1.Text = current.Symbol();      
                                        Button1.BackColor = current.Group().Color();      
                                        Button1.Text = current.Group().Name();      
                                    }      
                                    else      
                                    {      
                                        clearFields(exclude);      
                                    }      
                                    break      ;      
                            }      
   
                            ignore =       false      ;      
                        }      
   
                    private void  clearFields(int  exclude)  
                    {      
                        ignore =       true      ;      
                        switch (exclude)  
                        {      
                                case 0:  
                                    NumericUpDown1.Value = 0;      
                                    TextBox2.Text =       ""      ;      
                                    Button1.BackColor = SystemColors.Control;      
                                    Button1.Text =       ""      ;      
                                    break      ;      
                                case 1:  
                                    NumericUpDown1.Value = 0;      
                                    TextBox2.Text =       ""      ;      
                                    Button1.BackColor = SystemColors.Control;      
                                    Button1.Text =       ""      ;      
                                    break      ;      
                                case 2:  
                                    NumericUpDown1.Value = 0;      
                                    TextBox1.Text =       ""      ;      
                                    Button1.BackColor = SystemColors.Control;      
                                    Button1.Text =       ""      ;      
                                    break      ;      
                        }      
   
                        ignore =       false      ;      
                    }      
   
                    }      
      }  

The ElementDetails Class code



      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Drawing;
      using Lambda_Periodic_Table_Searcher_cs.gui;
   
      namespace Lambda_Periodic_Table_Searcher_cs.core
      {  
                    public class  ElementDetails  
                    {      
                        private int  _atomicNumber;  
                        private string  _symbol;  
                        private string  _element;  
                        private ElementType _type;  
                        public int  AtomicNumber()  
                        {      
                            return this._atomicNumber;  
                        }      
   
                        public string  Symbol()  
                        {      
                            return this._symbol;  
                        }      
   
                        public string  Element()  
                        {      
                            return this._element;  
                        }      
   
                        public ElementType Group()  
                        {      
                            return this._type;  
                        }      
   
                        public Bitmap Image()  
                        {      
                            Bitmap img =       new  Bitmap(120, 80);  
                            Graphics g = Graphics.FromImage(img);      
                            g.Clear(      this      .Group().Color());      
                            g.DrawRectangle(Pens.Black, 0, 0, 119, 79);      
                            StringFormat sf =       new  StringFormat();  
                            sf.Alignment = StringAlignment.Center;      
                            sf.LineAlignment = StringAlignment.Center;      
                         
                            Font smallFont =       new  Font("Microsoft Sans Serif", 8.25f, FontStyle.Regular);  
                            g.DrawString(      this      .AtomicNumber().ToString(),       new  Font(smallFont.FontFamily, 12, FontStyle.Bold), Brushes.Black, new Rectangle(0, 0, 120, 25), sf);  
                            g.DrawString(      this      .Symbol(),       new  Font(smallFont.FontFamily, 12, FontStyle.Bold), Brushes.Black, new Rectangle(0, 27, 120, 25), sf);  
                            g.DrawString(      this      .Element(), smallFont, Brushes.Black,       new  Rectangle(0, 52, 120, 25), sf);  
                            return img;  
                        }      
   
                        public ElementDetails(ElementType[] elementTypes, string[] fields)  
                        {      
                            this      ._atomicNumber = Convert.ToInt32(fields[0].Trim());      
                            this      ._symbol = fields[1].Trim();      
                            this      ._element = fields[2].Trim();      
                            this      ._type = elementTypes.Where(x => fields[3].Trim().Equals(x.Name())).First();      
                        }      
                    }      
      }  

Conclusion

This article teaches good programming practice through encapsulation, and composition, which are essential elements of good OOP Programming. Using Class objects, arrays and LINQ it's easy to create concise and effective programs in minutes, and your code will be readable industry standard code.


Other Resources

Download here... VB.Net / C#


See Also

VB.Net version