0

特定のクラスの新しいリストをインスタンス化するときに、どうにかしてパラメーターをリストに渡したいと思います。

より具体的には、次のようなことをしたいと思います。

List<FirstClass>(dataTable);
List<SecondClass>(dataTable);

コードの最初の行が呼び出された場合、コンストラクターは、後者が呼び出された場合よりも特定の方法で dataTable を処理します (FirstClass には異なるフィールドがあります)。

私が試したこと

namespace DeeMacsNamespace
{
    public class FirstClass
    {
        public String Title { get; set; }
        public String Url { get; set; }
    }

    public class FirstClass : List<FirstClass>
    {
        public FirstClass(DataTable table)
        {
            foreach (DataRow row in table.Rows)
            {
                this.Add(new FirstClass()
                {
                    Title = (String)row["Title"]
                });
            }
        }
    }
}

上記がうまくいくと思います(または少なくとも望んでいます)。DataTableしかし、特定のクラスの別のリストの非常によく似たコンストラクターから読み取るこのコードを最も効率的に再利用するにはどうすればよいでしょうか? FirstClassまた、コンストラクターがorSecondClass型からのものかどうかを確認する条件文を組み込むにはどうすればよいでしょうか? SecondClass の同様のコンストラクターでこれを書き直すことは避けたいと思います。

4

6 に答える 6

1
class FirstClass <T>
{
  if (typeof(T) == typeof(FirstClass))
  {
    // ... snip
  }
}

次に、他のすべてのクラスに から継承させFirstClassます。

于 2013-05-07T20:24:00.380 に答える
1

あなたの意図に関して、未回答の質問がいくつかあります。とはいえ、この一般的なセットアップは法案に適合する可能性があります。

public interface ISomeInterface
{
    String Title { get; set; }
    String Url { get; set; }
}

public class SecondClass : ISomeInterface
{
    public String Title { get; set; }
    public String Url { get; set; }
}

public class FirstClass : ISomeInterface
{
    public String Title { get; set; }
    public String Url { get; set; }
}

public class SomeClassCollection<T> : List<T> where T: ISomeInterface, new()
{
    public SomeClassCollection(DataTable table)
    {
        foreach (DataRow row in table.Rows)
        {
            this.Add(new T()
            {
                Title = (String)row["Title"]
            });
        }
    }
}

    private static void Main()
    {
        var table = new DataTable();
        var collection = new SomeClassCollection<FirstClass>(table);
    }
于 2013-05-07T20:28:57.377 に答える
1

私があなたを正しく理解していれば、次のようなものを使用してください。

class MyCollection<T> : Collection<T>
{
    public MyCollection(DataTable dataTable, Func<DataRow, T> itemsFactory)
        : base(dataTable.Rows.Cast<DataRow>().Select(row => itemsFactory(row)).ToList())
    {
    }
}

var firstClassCollection = new MyCollection<FirstClass>(dataTable, row => new FirstClass 
{
    Title = (String)row["Title"],
    Url = (String)row["Url"]
});
于 2013-05-07T20:20:06.910 に答える
0

次のような拡張メソッドを作成できます。

public static class DataTableEx
{
    public static IList<T> CreateList<T>(this DataTable dt,
                                         Func<DataRow,T> selector)
    {
        return dt.Rows.Cast<DataRow>().Select(selector).ToList();
    }
}

次に、次のように使用します。

IList<string> myList = 
    dataTable.CreateList(r => new FirstClass{Title = (string)r["Title"]});
于 2013-05-07T20:27:46.177 に答える
0
List<FirstClass> MyList1 = dataTable.Rows.Select(Row => 

      new FirstClass()
            {
                Title = (String)Row["Title"]
           }
    ).ToList();


List<SecondClass> MyList2 = dataTable.Rows.Select(Row => 
      new SecondClass() { the way you create second class } ).ToList();
于 2013-05-07T20:28:56.950 に答える
-1

まず第一に、2 つのクラスに同じ名前 (FirstClass と ListOfFirstClass) を持たせたくありません。

第二に、あなたの質問は少し不明確ですが、DataTable を First/SecondClass のリストに変換しようとしていると思います。

DataTable クラスにアクセスできる場合は、IEnumerable インターフェイスを実装できます。

Linq を使用すると、次のようなことができます。

using System.Linq;
public class DataTable : IEnumerable<T>
{
    IEnumerable<T> IEnumerable<T>.GetEnumerator()
    {
        return from row in rows
               where FindIfRowIsOfClass<T>(row)
               select new T(row);
    }
}

汎用の IEnumerable メソッドも実装し、FindIfRowIsOfClassT メソッドに入力する必要があります。これは、ほとんどの場合、適切なフィールドがあるかどうかを調べることによって行われます。

結果は実行する能力です

List<FirstClass> listOfFirstClass = new List<FirstClass>(dataTable.GetEnumerator<FirstClass>);

100% 確信があるわけではありませんが、実際には GetEnumerator を明示的に呼び出さなくても済む可能性があります。List がそれを行う可能性があります。

アクセスできない場合は、手動で行うことができます。

var enumerableFirstClass = from row in dataTable.rows
                           where <insert row is FirstClass check>
                           select new FirstClass(){Title = (string)row["Title"]};
List<FirstClass> listOfFirstClass = new List<FirstClass>(enumerableFirstClass);

お役に立てれば。

ハッピーコーディング!

于 2013-05-07T20:34:28.007 に答える