0

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

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

4 回答 4

1

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

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

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 上询问内容)并编写映射配置文件。

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

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

于 2013-09-12T10:48:35.110 回答
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]);
于 2013-09-12T10:39:52.600 回答
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;
        }
    });

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

于 2013-09-12T10:52:36.597 回答
0

尝试这样的事情:

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

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

于 2013-09-12T09:44:41.877 回答