传递通用列表 [英] Passing a generic List

查看:56
本文介绍了传递通用列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两节课. Admin.cs和Arog.cs

Prog.cs继承Admin.cs

admin.cs包含3个变量(姓,名,薪)
prog.cs由Admin.cs中的3个变量和5种不同的技能组成

这5个技能由5个复选框组成,我可以在其中选中(或者打勾)其中的任何一个甚至可能超过1个
我希望能够将这5种技能存储在通用列表中(不使用数组的原因是,编可能具有1种技能,甚至最多5种技能).

选中必要的复选框并按命令按钮添加名称,ID,薪水后,我想在列表框中进一步添加对象.

这是我正在使用的管理员,它可以正常工作

I have two classes. Admin.cs and Arog.cs

Prog.cs inherits Admin.cs

admin.cs consists of 3 variables (surname,id,salary)
prog.cs consists of the 3 variables in Admin.cs and 5 different skills

the 5 skills consist of 5 check boxes where I can check(ie Tick) any of them maybe even more than 1

I want to be able to store these 5 skills in a generic list (the reason of not using an array is because prog can have either 1 skill or even up to 5 skills)

Once I have the necessary check boxes checked and name,id,salary y pressing a command button add, I want to further add the object in a list box.

this is what I am using for the admin and it works OK

c = new admin(txtSurname.Text, txtID.Text, Convert.ToDouble(txtSalary.Text));



当我将其添加到编中时,我会得到
smith 123YRR1 18000.00 System.collections.GenericList''1 [System.String]



when i am adding the to the prog I just get
smith 123YRR1 18000.00 System.collections.GenericList''1[System.String]

List<string> sk = new List<string>();
if (chkA.Checked == true)
          {
              skills.Add("A");
          }
          if (chkB.Checked == true)
          {
              skills.Add("B");
          }
          if (chkC.Checked == true)
          {
              skills.Add("C");
          }
          if (chkD.Checked == true)
          {
              skills.Add("D");
          }
          if (chkE.Checked == true)
          {
              skills.Add("E");
          }

c = new Prog(txtSurname.Text, txtID.Text,Convert.ToDouble(txtSalary.Text),sk);

//class prog
class Prog : Admin
    {
        //string skills;
        List<string> sk; //= new List<string>();

        public prog(string surname, string id, double salary,List<string>sk)
            : base(surname,id,salary)
        {
            this.sk = sk;
        }
        public override string ToString()
        {
            return base.ToString()+ this.sk;
        }



如何传递通用列表?这样我才能填写我的列表框?

示例列表框应显示

史密斯123YRR1 18000.00 A C D

A C D是技能



How can I pass the generic list ? so that I can fill my list box ?

example the list box should show

smith 123YRR1 18000.00 A C D

where A C D are skills

推荐答案

我认为这可能是您在寻找的东西:

I think this might be what you''re looking for:

class Prog : Admin
    {
    List<string> sk = new List<string>();

    // ...


    public override string ToString()
        {
        return base.ToString() + " " + string.Join(" ", sk);
        }
    }


我确切地知道该怎么做.我将为您提供两种解决方案:一种是更基本的解决方案,一种是更高级的解决方案.您可能希望使其更简单,从而避免下载我的代码等.

实际上,您的示例是演示正确技术的完美示例(我的5个!).

现在,将您的5个技能结合在一起,因为您有复选框而不是单选框,对吗?这意味着技能集仅由5位表示.让我们遵循简单的逻辑.实现位集数据的最佳方法是:

I know exactly what to do. I''m going to give you two solutions: one is more basic, one more advanced. You may want to keep it more simple, which will allow you to avoid downloading my code, etc.

Actually your example is the perfect one to demonstrate right technique (my 5!).

Now, your 5 skills are combined, as your have check boxes, not radio boxes, right? It means the skill set is represented by just 5 bits. Let''s follow simple logic. Best way to implement bit set data is this:

[System.Flags]
enum SkillSet : byte {
    None = 0,
    A = 1 << 1,
    B = 1 << 2, 
    C = 1 << 3,
    D = 1 << 4, 
    E = 1 << 5,
} //enum SkillSet



换句话说,A = 1, B = 2, C = 4,..等.
要检查技能集中的一项技能,请使用:



In other words, A = 1, B = 2, C = 4,.. etc.
To check up a skill in a skill set, use:

static bool HasSkill(SkillSet skillSet, SkillSet skill) {
     return (skillSet & skill) == skill;
}



这是如何组合技能的方法:



And this is how to combine skills:

SkillSet mySkills = SkillSet.A | SkillSet.C | SkillSet.E;



这是用SkillSet Value值填充控件的方法:



This is how to populate your controls with some value of SkillSet Value:

chkA.Checked = HasSkill(Value, SkillSet.A);
chkB.Checked = HasSkill(Valie, SkillSet.B);
//...



UI用户进行编辑时,这是从控件中提取SkillSet值的方法:



This is how to extract SkillSet Value from controls when editing is done by the UI user:

Value = SkillSet.None;
if (chkA.Checked == true)
    SkillSet |= SkillSet.A;
if (chlA.Checked == true)
    SkillSet |= SkillSet.B;
//..., etc.



就这样.

您不需要任何清单.一个人的完整技能集用一个字节大小的位集表示.
另外,请注意,您不必使用任何硬编码的字符串值.使用任何常量的唯一地方是枚举类型本身的定义-完全可支持的方式.

甚至控件的名称也可以从此枚举类型中生成.注意属性System.Flags.
此属性仅影响枚举类型的值的字符串表示形式.
考虑与SkillSet value = SkillSet.A + SkillSet.C相同的SkillSet value = (SkillSet)5.使用该属性,value.ToString()将返回"5";使用Flags属性将返回"A,C"-试试看.

关于检查布尔值chkA.Checked == true的一点说明.坦白说,只有chkA.checked会执行相同的操作,但前提是该属性的类型为bool.
WPF复选框的属性使用不同的类型:bool?.此类型为 nullable ,也就是说,它使用3值集:{null, False, True},而不是通常的布尔值集{False, True}.因此,支票不会返回bool,而是会返回bool?.

学习.NET,女士们,先生们!可能比您想的要深一些.

下一步,我将根据我最近的工作,,建议一些更高级的技术. .

非常感谢您的关注!



That''s it.

You don''t need any list. Complete skill set of one person is expressed with a single bit set of the size of byte.
Also, note you don''t have to use any hard-coded string values. The only place use any constants is the definition of the enumeration type itself -- perfectly supportable way.

Even the name of the controls can be generated out of this enumeration type. Pay attention for the attribute System.Flags.
This attribute only effect string representation of the value of the enumeration type.
Consider SkillSet value = (SkillSet)5, same as SkillSet value = SkillSet.A + SkillSet.C. With the attribute, value.ToString() will return "5"; using Flags attribute will return "A, C" -- try it.

A little note on the check up of the boolean value chkA.Checked == true. Frankly, just chkA.checked would do the same, but only if the property has the type bool.
The property of the WPF check box uses different type: bool?. This type is nullable, that is, instead of usual boolean value set of {False, True} it uses 3-value set: {null, False, True}. So, the check would not return bool, it would return bool?.

Learn .NET, Ladies and Gentlemen! It''s a bit deeper then you might thought.

As a next step, I will advice somewhat more advanced technique, base of my relatively recent work, this one.

Thank you very much for attention!


我答应添加比 Answer 1 更高的配方.

要使用我的方法,您需要查看我的文章枚举类型不枚举!解决.NET和语言限制(用于基于枚举的迭代和数组索引的通用类),并下载
I promised to add more advanced recipe then that of Answer 1.

To use my method, you need to see my article Enumeration Types do not Enumerate! Working around .NET and Language Limitations (Generic classes for enumeration-based iteration and array indexing) and download the code.

We need to use this:

using SA.Universal.Enumerations;



我的库提供了通用类,用于通过枚举值和由枚举成员索引的数组进行迭代.您的应用程序同时需要它们.对于基本枚举类型,我们可以使用答案3 中显示的一种,并进行以下修改:



My library offers generic classes for iteration through enumeration values and array indexed by enumeration members. Your application requires them both. For base enumeration type we can use the one shown in Answer 3, with one modification:

[System.Flags]
enum SkillSet {
    [NonEnumerable] None = 0,
    A = 1 << 1,
    B = 1 << 2,
    C = 1 << 3,
    D = 1 << 4,
    E = 1 << 5,
} //enum SkillSet



我们将在您的表单中需要两个变量,一个用于迭代,另一个用于存储复选框数组:



We shall need two variables in you form, one for iteration, another to store an array of check boxes:

Enumeration<SkillSet> SkillSetEnumeration
    = new Enumeration<SkillSet>();
EnumerationIndexedArray<SkillSet, CheckBox> SkillSetControl
    = new EnumerationIndexedArray<SkillSet, CheckBox>();



复选框可以在运行时创建,并根据枚举类型自动设置.

我们需要在某处定义一些复选框的布局:



Check boxes can be created during run-time and automatically set up according to the enumeration type.

We need to have definition of for some check boxes layout somewhere:

const int CheckBoxTop = 8;
const int CheckBoxInterval = 2;
const int CheckBoxLeft = 4;



调用以下设置方法的一个好地方是在表单构造函数的末尾(或之后的任何时间,但在显示表单之前).



A good place to call the following set up method is at the end of form constructor (or any time later, but before showing the form).

void Populate() {
    Control parent = this.panelTests;
    int current = CheckBoxTop;
    foreach (var item in SkillSetEnumeration) {
        CheckBox cb = new CheckBox();
        parent.Controls.Add(cb);
        cb.Top = current;
        cb.Left = CheckBoxLeft;
        current += cb.Height + CheckBoxInterval;
        cb.Text = item.Name;
        SkillSetControl[item.EnumValue] = cb;
   } //loop
} //void Populate



最后,现在,我们可以拥有一个UI属性,该属性从一组复选框控件获取SkillSet值,或将此值转换(设置)为这些控件的Checked状态:



And, finally, now we can have a UI property which gets SkillSet value from a set of check box control or translates (sets) this value to the Checked state of those controls:

SkillSet SkillSetControlValue {
     get { //controls to value
         SkillSet value = SkillSet.None;
         foreach (var item in SkillSetEnumeration) {
             if (SkillSetControl[item.EnumValue].Checked)
                 value |= item.EnumValue;
         } //loop
         return value;
     } //SkillSetControlValue get
     set { //values to control
         foreach (var item in SkillSetEnumeration)
             SkillSetControl[item.EnumValue].Checked =
                 (item.EnumValue & value) > 0;
         } //SkillSetControlValue set
} //SkillSetControlValue



就是这样!



That''s all!


这篇关于传递通用列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆