Converting a C# method to use generics referencing a property inside
I would like to convert a method to use generics. It is currently hard-coded to these types:
DataContext.Document
in the data context's partial class and inheriting fromobject
DataContext.Documents
also in this partial class and inheriting fromLinq.Table<Document>
Import.Document
inheriting from a custom classImportObject
Original method:
public void ProcessDocuments(Delegate method, params object[] args)
{
using (DataContext dc = new DataContext())
{
dc.ObjectTrackingEnabled = false;
// Map from DataContext object to ImportObject
Mapper.CreateMap<Document, Import.Document>();
// Loop through DataContext objects
foreach (Document d in dc.Documents)
{
Import.Document doc = Mapper.Map<Document, Import.Document>(d);
args[0] = doc;
method.DynamicInvoke(args);
}
}
}
Attempted method:
public void ProcessImportObjects<TSource, TDestination>
(Action<TDestination, ImportDataSource, int> processMethod, ImportDataSource import开发者_开发百科Source, int resultId)
{
using (DataContext dc = new DataContext())
{
dc.ObjectTrackingEnabled = false;
Mapper.CreateMap<TSource, TDestination>();
foreach (TSource d in dc.Documents) // PROBLEM: Hard-coded reference to property on DataContext
{
TDestination doc = Mapper.Map<TSource, TDestination>(d);
processMethod(doc, importSource, resultId);
}
}
}
(Here, TDestination
should be of type ImportObject
but I'm not sure how to express that.)
As shown in the comment, the foreach needs to reference a property on the DataContext that is an IEnumerable<TSource>
.
Does this mean I need to pass the DataContext in as a parameter or is there a better way?
It sounds like you need to parameterize the property name in DataContext
. One way to do it is to pass in a function that takes a DataContext
and returns your enumerable (a Func<DataContext, IEnumerable<TSource>>
) and then you would pass in a lambda like dc => dc.Document
as that parameter.
Another option, which would work (but without type-safety) is to pass in the property's name as a string and then use Reflection to access it.
public void ProcessImportObjects<TSource, TDestination>
(Func<DataContext, IEnumerable<TSource>> dcProperty,
Action<TDestination, ImportDataSource, int> processMethod,
ImportDataSource importSource,
int resultId)
{
using (DataContext dc = new DataContext())
{
dc.ObjectTrackingEnabled = false;
Mapper.CreateMap<TSource, TDestination>();
foreach (TSource d in dcProperty(dc))
{
TDestination doc = Mapper.Map<TSource, TDestination>(d);
processMethod(doc, importSource, resultId);
}
}
}
精彩评论