循环遍历类集合并识别它们以添加新类

本文关键字:添加 新类 识别 遍历 集合 合并 循环 | 更新日期: 2023-09-27 18:30:50

我有一组带有属性的类和一个包含一组类列表的主类。

public class MainClass
{
    public List<ClassA> listA {get;set;}
    public List<ClassB> listB {get;set;}
    public List<ClassC> listC {get;set;}
    public object[] loop = {listA, listB, listC};
}
class ClassA
{
    public Guid id {get;set;}
    public string text {get;set;}
    public int number {get;set}
    public status {get;set;}
    public object[] loop = {id, text, number};
}
class ClassB
{
    public Guid id {get;set;}
    public string text {get;set;}
    public Image pic {get;set}
    public status {get;set;}
    public object[] loop = {id, text, pic};
}
class ClassC
{
    public Guid id {get;set;}
    public byte[] data {get;set;}
    public DateTime date {get;set;}
    public status {get;set;}
    public object[] loop = {id, data, date};
}
public enum status
{
    nothing=0, instert=1, delete=2, edit=3
}

自昨天以来情况发生了变化,但我仍然想索引我的班级,我的想法是添加这一行:

public object[] loop = {listA, listB, listC};

到 MainClass,将这个目标存档,在将整个事情更改为非静态类后,这似乎是被禁止的。 此外,当我尝试使用静态类执行此操作时,我无法直接处理我的列表。 这能做到吗?

最后,我想像这样解决列表中的特定属性:

MainClass mc = new MainClass();
DateTime dt = mc.loop[2][5].loop[2];

即使没有 loop 属性这样做会更好,例如:

DateTime dt = mc[2][5][2];

我想如何循环它最终:

for(int i=0; i<mc.loop.count(); i++)
{
    for (int j=0; j<mc.loop[i].Count(); i++)
    {
        switch(mc.loop[i][j].loop[3])
        {
            case: delete
                doSomething1(mc.loop[i][j])
            case: insert
                doSomething2(mc.loop[i][j])
            case: edit
                 doSomething3(mc.loop[i][j])
            default
                 break;
        }
    }
}

循环遍历类集合并识别它们以添加新类

正如我在评论中所写的,你应该简单地使用对象关系映射框架,因为你显然试图将映射从你的域抽象到数据库中。

话虽如此,您可以使用反射来概括整个事情。如果您不打算添加复杂的映射规则,您将拥有类似于以下内容的内容:

foreach (var propertyInfo in myClass.GetType().GetProperties())
{
    var name = propertyInfo.Name;
    var value = propertyInfo.GetValue(myClass);
    // do stuff
    Console.WriteLine("Value of {0} is {1}", name, value ?? "null");
}

一个合适的ORM做的远不止这些。If 允许您为每个属性定义特定的映射规则。嵌套对象和一对多关系的自动映射。它执行大量复杂的缓存,以避免与反射(更重要的是数据库访问)相关的性能损失。它允许通过延迟查询来延迟访问数据库,直到需要数据。它跟踪更改了哪些属性并自动更新它们。所有这些都是通过包含对库的引用,花一两天时间查看示例(并在Stack Overflow上询问内容)并编写映射配置文件来实现的。

或者,您可以通过代码定义映射,以获得完整的智能感知和更好的类型安全性:

// fluent nhibernate example
public class CatMap : ClassMap<Cat>
{
    public CatMap()
    {
        // define which properties are going to be saved, and how
        Id(x => x.Id);
        Map(x => x.Name).Length(16).Not.Nullable();
        Map(x => x.Sex);
        References(x => x.Mate);
        HasMany(x => x.Kittens);
    }
}

您现在正在做的事情是维护的噩梦。您正在实施一个规则,其中每个数据类都需要将其属性公开为对象数组(并考虑如何以这种方式更新其值)。此外,您将失去所有类型安全性,因为您最终会得到普通对象。知道您正在访问哪个属性的唯一方法是通过 loop 数组的索引,这意味着您将在整个代码中使用大量if条件和幻数。作为不应该如何完成事情的练习,这很好,但不要允许它最终出现在生产代码中,否则您将花费无数小时修复错误和更改代码以添加新功能。

尝试这样的事情:

MainClass mc = new MainClass();
DateTime dt = ((ClassA) mc.loop[2]).date;

我仍然不确定你真正想要什么以及所有这些索引有什么用......

1)要丢弃循环变量,您可以像这样创建类索引器

private object[] loop = {id, text, number};
public int this[int index]
{
    get { return loop[index]; }
    set { loop[index] = value; }
}

2)为了能够检索变量,您可能必须将它们从对象转换为它们的实际类型才能使用它们的功能。这仍然是不切实际的。

DateTime dt = ((DateTime) ((ClassA)mc[0]) [2]);

好的,不确定你在做什么,但这个怎么样

public enum Status
{
    Nothing = 0,
    Insert,
    Delete,
    Edit
}
public abstract class Searchable
{
    public virtual Guid Id { get; set; }
    public virtual Status Status { get; set; }
    protected internal abstract IEnumerable SearchableProperties { get; }
}
public class ClassA : Searchable
{
    public string Text { get; set; }
    public int Number { get; set; }
    protected internal override IEnumerable SearchableProperties
    {
        get
        {
            yield return Text;
            yield return Number;
        }
    }
}
public class ClassB : Searchable
{
    public string Text { get; set; }
    public Image Pic { get; set; }
    protected internal override IEnumerable SearchableProperties
    {
        get
        {
            yield return Text;
            yield return Pic;
        }
    }
}
public class ClassC : Searchable
{
    public byte[] Data { get; set; }
    public DateTime Date { get; set; }
    protected internal override IEnumerable SearchableProperties
    {
        get
        {
            yield return Data;
            yield return Date;
        }
    }
}

然后你可以像这样编写你的主类,

public class Searchables
{
    public List<ClassA> ListA { get; set; }
    public List<ClassB> ListB { get; set; }
    public List<ClassC> ListC { get; set; }
    public void SearchContents(Action<Status, Searchable, object> visitor)
    {
        SearchContent(this.ListA, visitor);
        SearchContent(this.ListB, visitor);
        SearchContent(this.ListC, visitor);
    }
    private static void SearchContent(
            IEnumerable<Searchable> searchees,
            Action<Status, Searchable, object> visitor)
    {
        foreach (var searchee in searchees)
        {
            visitor(searchee.Status, searchee, searchee.Id);
            foreach (var property in searchee.SearchableProperties)
            {
                visitor(searchee.Status, searchee, property);
            }
        }
    }
}

然后你所要做的就是写下访客...

var mainClass = new Searchables();
....
mainClass.SearchContent((status, searchee, property) =>
    {
        switch(status)
        {
            case Status.Delete:
                // DoSomthing1 ...
                break;
        }
    });

但是,这一点不在你的问题中。