I have a Dictionary:
Dictionary<int, Type> AllDrillTypes = new Dictionary<int, Type>()
{
{13,typeof(TCHEMISTRY)},
{14,typeof(TDRILLSPAN)}
};
where TCHEMISTRY and TDRILLSPAN are classes. Then I want to get rows from one of this classes like this:
Type T = AllDrillTypes[13];
var LC = Activator.CreateInstance( typeof(List<>).MakeGenericType( T ) );
MethodInfo M = T.GetMethod("FindAll", BindingFlags.Public | BindingFlags.Static, null, new Type[] { }, null);
LC = M.Invoke(null, new object[] { });
All this code works correctly. After that I need to get some rows like this:
var LingLC = from obj in LC where obj.RunID == 1001 select obj;
But this line causes error:
"Could not find an implementation of the query pattern for source type 'object'. 'Where' not found."
What's wrong with this code line?
Even if you can't change the class definitions, you can avoid using reflection:
// Getter dictionary rather than type dictionary.
Dictionary<int, Func<IEnumerable<object>>> DrillTypeGetters =
new Dictionary<int, Func<IEnumerable<object>>>()
{
{ 13, () => TCHEMISTRY.FindAll().Cast<object>() },
{ 14, () => TDRILLSPAN.FindAll().Cast<object>() }
};
Dictionary<int, Func<object, int>> IDGetters =
new Dictionary<int, Func<object, int>>()
{
{ 13, o => ((TCHEMISTRY)o).RunID },
{ 14, o => ((TDRILLSPAN)o).RunID }
};
IEnumerable<object> LC = DrillTypeGetters[13]();
IEnumerable<object> LingLC =
from obj in LC
where IDGetters[13](obj) == 1001
select obj;
Or you could even just switch on 13
/14
and run a completely different method per type.
if (choice == 13)
IEnumerable<TCHEMISTRY> LingLC =
TCHEMISTRY.FindAll().Where(tc => tc.RunID == 1001);
else if (choice == 14)
IEnumerable<TDRILLSPAN> LingLC =
TDRILLSPAN.FindAll().Where(td => td.RunID == 1001);
Basically, if the two classes don't share any common hierarchy, you can't write any common code to deal with them. If they have lots of similar properties, you can use getters as in my first example to provide a way to get the similar properties whatever type of class you're dealing with. If they don't even have similar properties, don't try to write shared code.
Maybe you could rewrite your code to something like this, .... to get a more type-safe solution (without using reflection).
void Main()
{
var driller1 = new DrillerWhichYouCannotChange1();
var driller2 = new DrillerWhichYouCannotChange2();
var allDrillTypes = new Dictionary<int, IList<IDriller>>()
{
{ 13, new List<IDriller>() { new DrillerWhichYouCannotChange1Adapter(driller1) } },
{ 14, new List<IDriller>() { new DrillerWhichYouCannotChange2Adapter(driller2) } },
};
Console.WriteLine(allDrillTypes[13][0].SomeCommonProperty); // prints 123
Console.WriteLine(allDrillTypes[14][0].SomeCommonProperty); // prints 456
}
interface IDriller
{
int SomeCommonProperty { get; }
}
class DrillerWhichYouCannotChange1Adapter : IDriller
{
private DrillerWhichYouCannotChange1 inner;
public DrillerWhichYouCannotChange1Adapter(DrillerWhichYouCannotChange1 inner)
{
this.inner = inner;
}
public int SomeCommonProperty { get { return this.inner.PropertyX; } }
}
class DrillerWhichYouCannotChange2Adapter : IDriller
{
private DrillerWhichYouCannotChange2 inner;
public DrillerWhichYouCannotChange2Adapter(DrillerWhichYouCannotChange2 inner)
{
this.inner = inner;
}
public int SomeCommonProperty { get { return this.inner.PropertyY; } }
}
class DrillerWhichYouCannotChange1
{
public int PropertyX { get { return 123; } }
}
class DrillerWhichYouCannotChange2
{
public int PropertyY { get { return 456; } }
}
EDIT: If you cannot change the driller classes, you could use the adapter-pattern to create one adapter per driller, which implements IDiller
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With