循环遍历一组类并识别它们以添加新类

时间:2013-09-10 10:56:44

标签: c# .net visual-studio class loops

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

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];

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

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;
        }
    }
}

4 个答案:

答案 0 :(得分:1)

正如我在评论中所写的那样,您应该只使用Object-Relational Mapping框架,因为您显然是在尝试将您的域中的映射抽象到数据库中。

话虽如此,你可以使用Reflection概括整个事物。如果您不打算添加复杂的映射规则,那么您将拥有类似于:

的内容
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比这更有用。如果允许您为每个属性定义特定的映射规则。嵌套对象和一对多关系的自动映射。它执行大量复杂的缓存以避免与反射相关的性能损失(更重要的是,数据库访问)。它允许通过延迟查询来延迟访问数据库,直到需要数据。它跟踪哪些属性已更改并自动更新它们。通过包含对库的引用,花一两天时间查看示例(以及在Stack Overflow上询问内容)并编写映射配置文件。

或者,您可以定义mappings through code以获得完整的智能感知和更好的类型安全性:

// 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条件和幻数。作为不应该做的事情的练习,这很好,但是不要让它最终出现在生产代码中,否则你将花费无数个小时修复错误并更改代码以添加新功能。

答案 1 :(得分:0)

尝试这样的事情:

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

我仍然不确定你真正想要的是什么以及那些索引是什么......

答案 2 :(得分:0)

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]);

答案 3 :(得分:0)

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

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;
        }
    });

但是,那个位不在您的问题中。