Reputation:
I'd like to somehow pass a parameter into a list when I'm instantiating a new list of certain classes.
More specifically, I'd like to do something like the following:
List<FirstClass>(dataTable);
List<SecondClass>(dataTable);
If the first line of code is called, the constructor will deal with dataTable in a certain way than if the latter is called (FirstClass has different fields).
What I've Tried
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"]
});
}
}
}
}
I'm assuming (or at least hoping), the above will work. But how do I then most efficiently reuse this code that reads from a DataTable
in a really similar constructor for another list of a certain class? And how do I incorporate a conditional statement to check whether the constructor is from the FirstClass
or SecondClass
type? I would like to avoid rewriting this for a similar constructor for SecondClass.
Upvotes: 0
Views: 1116
Reputation: 44275
There's some unanswered questions regarding your intent. That being said this generic setup may fit the bill:
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);
}
Upvotes: 1
Reputation: 5575
First of all, you don't want to have the two classes have the same name (the FirstClass and the ListOfFirstClass).
Second of all, your question is a bit unclear, but I believe you're trying to turn a DataTable into a list of First/SecondClass.
If you have access to the DataTable class, you can have it implement the IEnumerable interface.
Using Linq, you can do comething like:
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);
}
}
You'll have to implement the generic IEnumerable method as well, and fill out the FindIfRowIsOfClassT method. This will most likely be done by finding out if it has the right fields.
The result is the ability to do
List<FirstClass> listOfFirstClass = new List<FirstClass>(dataTable.GetEnumerator<FirstClass>);
I'm not 100% sure, but you may actually be able to get away with not calling GetEnumerator explicitly, List might do that for you.
If you don't have access to that, you can do it manually:
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);
Hope this helps.
Happy coding!
Upvotes: -1
Reputation: 86600
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();
Upvotes: 0
Reputation: 120400
You could write an extension method such as:
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();
}
}
Then use it as follows:
IList<string> myList =
dataTable.CreateList(r => new FirstClass{Title = (string)r["Title"]});
Upvotes: 0
Reputation: 9399
class FirstClass <T>
{
if (typeof(T) == typeof(FirstClass))
{
// ... snip
}
}
Then have all other classes inherit from FirstClass
.
Upvotes: 1
Reputation: 37760
If I've understood you correctly, then use something like this:
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"]
});
Upvotes: 1