为什么使用for或foreach与TabPage.Controls有区别?

本文关键字:TabPage Controls 有区别 foreach for 为什么 | 更新日期: 2023-09-27 18:04:09

我有一个问题,那就是:

TabPage tab = new TabPage();
[...]
for (int i = 0; i < tab.Controls.Count; i++)
{
   Debug.WriteLine(i + " - " + tab.Controls[i].Name + " - " + tab.Controls[i].Text);
}

的结果显然与

不同。
TabPage tab = new TabPage();
[...]
int j = 0;
foreach (Control ctl in tab.Controls)
{
    Debug.WriteLine(j + " - " + ctl.Name + " - " + ctl.Text);
    j++;
}
for循环在我的例子中有结果53项(Count显示53),但是foreach循环只有27项。

我不能理解这个。原因是什么呢?

为什么使用for或foreach与TabPage.Controls有区别?

我现在可以自己解决这个问题了:

第二个源代码不像发布的那样,它是这样的:

TabPage tab = new TabPage();
[...]
int j = 0;
foreach (Control ctl in tab.Controls)
{
    Debug.WriteLine(j + " - " + ctl.Name + " - " + ctl.Text);
    tab2.Controls.Add(ctl);
    j++;
}

=>所以我移动意外我的控制在foreach循环,但我只想克隆它,这就是答案如何做到这一点:克隆控件- c# (Winform)

现在我像这样修改:

foreach (Control ctl in tab1.Controls)
{
    try
    {
        if (ctl != null)
        {
            object obj_clone = CloneObject(ctl);
            if (obj_clone != null && obj_clone is Control)
            {
                Control ctl_clone = (Control)CloneObject(ctl);
                tab2.Controls.Add(ctl_clone);
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception: " + ex.Message + " - TargetSite:" + ex.TargetSite + " - Source: " + ex.Source + " - InnerException: " + ex.InnerException.Message.ToString());
    }
}
private Object CloneObject(Object obj)
{
    var typ = obj.GetType();
    var obj_clone = CreateInstanceOfType(typ);
    PropertyInfo[] controlProperties = typ.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (PropertyInfo propInfo in controlProperties)
    {
        if (propInfo.CanWrite && propInfo.Name != "WindowTarget")
        {
            try
            {
                if (propInfo.PropertyType.IsValueType || propInfo.PropertyType.IsEnum || propInfo.PropertyType.Equals(typeof(System.String)))
                {
                    propInfo.SetValue(obj_clone, propInfo.GetValue(obj));
                }
                else
                {
                    object value = propInfo.GetValue(obj);
                    if (value == null)
                        propInfo.SetValue(obj_clone, null);
                    else
                        propInfo.SetValue(obj_clone, CloneObject(value));
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception: " + ex.Message + " - TargetSite:" + ex.TargetSite + " - Source: " + ex.Source + " - InnerException: " + ex.InnerException.Message.ToString());
            }
        }
    }
    return (Object)obj_clone;
}
public object CreateInstanceOfType(Type type)
{
    // First make an instance of the type.
    object instance = null;
    // If there is an empty constructor, call that.
    if (type.GetConstructor(Type.EmptyTypes) != null)
        instance = Activator.CreateInstance(type);
    else
    {
        // Otherwise get the first available constructor and fill in some default values.
        // (we are trying to set all properties anyway so it shouldn't be much of a problem).
        ConstructorInfo ci = type.GetConstructors()[0];
        ParameterInfo[] parameters = ci.GetParameters();
        object[] ciParams = new object[parameters.Length];
        for (int i = 0; i < parameters.Length; i++)
        {
            if (parameters[i].DefaultValue != null)
            {
                ciParams[i] = parameters[i].DefaultValue;
                continue;
            }
            Type paramType = parameters[i].ParameterType;
            ciParams[i] = CreateInstanceOfType(paramType);
        }
        instance = ci.Invoke(ciParams);
    }
    return instance;
}