Consider the following code:
public interface IIdentifiable<T>
{
T Id { get; set; }
}
public interface IViewModel
{
}
public class MyViewModel1 : IViewModel, IIdentifiable<int>
{
public string MyProperty { get; set; }
public int Id { get; set; }
}
public class MyViewModel2 : IViewModel, IIdentifiable<string>
{
public string MyProperty { get; set; }
public string Id { get; set; }
}
I also have class that operates with ViewModels:
public class Loader<T> where T: IViewModel
{
public void LoadData()
{
/*some important stuff here*/
if (typeof(IIdentifiable<??>).IsAssignableFrom(typeof(T)))
{ // ^- here's the first problem
data = data.Where(d => _dataSource.All(ds => ((IIdentifiable<??>) ds).Id != ((IIdentifiable<??>) d).Id)).ToList();
} // ^---- and there the second ----^
/*some important stuff here too*/
}
}
Now, as you can see, viewmodels that I have might implement the IIdentifiable<>
interface. I want to check that, and if it's true,
I want to make sure my data
list does not contains any entry that are already present in my _dataSourse
list.
So I have 2 questions:
I don't know what
IIdentifiable<>
has in its generic parentheses, it might beint
,string
or evenGUID
. I triedtypeof(IIdentifiable<>).IsAssignableFrom(typeof(T))
which is the correct syntax, yet it always returnsfalse
. Is there a way to check whetherT
isIIdentifiable<>
without knowing the exact generic type?If there is an answer for the first question, I would also like to know how can I compare the
Id
fields without knowing their type. I found this answer quite useful, yet it doesn't cover my specific case.
I know that I probably can solve that problem if I make my Loader<T>
class a generic for two types Loader<T,K>
, where K
would be the
type in IIdentifiable<>
, yet I would like to know if there are other solutions.
P.S. In addition to my first question: I'm also curious why one can write something like this typeof(IIdentifiable<>).IsAssignableFrom(typeof(T))
if it returns false when the generic type of IIdentifiable<>
is not specified?
Edit: I guess, in hindsight, I understand why I can't write the code this bluntly - because there's might be the collection ICollection<IViewModel>
where the entries implement different types of IIdentifiable<>
(or don't implement it at all), and the check like that would fail awkwardly. Yet maybe there is a way to do something like that with some restrictions, but without creating second generic parameter to my Loader
?