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 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 は、これ以上のことを行います。プロパティごとに特定のマッピング ルールを定義できる場合。ネストされたオブジェクトと 1 対多の関係の自動マッピング。リフレクション (およびさらに重要なデータベース アクセス) に関連するパフォーマンスの低下を回避するために、多くの複雑なキャッシュが行われます。データが必要になるまでクエリを延期することで、データベースへの遅延アクセスを可能にします。どのプロパティが変更されたかを追跡し、それらを自動的に更新します。そして、ライブラリへの参照を含め、1 日か 2 日かけて例を見て (そして Stack Overflow で質問して)、マッピング構成ファイルを作成します。

または、コードを使用してマッピングを定義して、完全な IntelliSense とより優れた型の安全性を得ることができます。

// 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

このようなことを試してください:

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

それでも、あなたが本当に何を望んでいるのか、それらすべてのインデックスが何のためにあるのかわかりません...

于 2013-09-12T09:44:41.877 に答える