6

I have several templated objects that all implement the same interface:

I.E.

MyObject<datatype1> obj1; MyObject<datatype2> obj2; MyObject<datatype3> obj3; 

I want to store these objects in a List... I think I would do that like this:

private List<MyObject<object>> _myList; 

I then want to create a function that takes 1 parameter, being a datatype, to see if an object using that datatype exists in my list.... sorta clueless how to go about this. In Pseudo code it would be:

public bool Exist(DataType T) { return (does _myList contain a MyObject<T>?); } 

Some Clarification....

My interface is IMyObject<T>, my objects are MyObject<T>. I have a new class MyObjectManager which I need to have a List of MyObject<T> stored within. I need a function to check if a MyObject<T> exists in that list. The type T are datatypes which were auto-generated using T4.... POCO classes from my Entity Data Model.

4
  • What if it contains a MyObject<U> and U inherits T? Commented May 27, 2010 at 17:48
  • Well my U is auto generated using T4 and EF POCO classes. Commented May 27, 2010 at 17:50
  • Do the classes inherit each-other? Commented May 27, 2010 at 17:51
  • No, by default they do not inherit from anything. Commented May 27, 2010 at 17:53

3 Answers 3

6

You can make a generic function:

public bool Exists<T>() where T : class { return _myList.OfType<MyObject<T>>().Any(); } 

Note that this requires that you know T at compile-time.

If all you have is a System.Type object at runtime, you'll need to use reflection:

public bool Exists(Type t) { var objectOfT = typeof(MyObject<>).MakeGenericType(t); return _myList.Any(o => o.GetType() == objectOfT); } 

Note, however, that a List<MyObject<object>> cannot hold a MyObject<SomeType>.
You need to change the list to a List<object>, or make MyObject implement or inherit a non-generic type and make the list contain that type.

Sign up to request clarification or add additional context in comments.

2 Comments

My class that stores the list will not have a generic type, However the T in MyObject<T> is known at compile time and the namespace for these objects are referenced in this class. When I try your first example it says The type T must be a reference type in order to use it as a parameter. I want T to be a generic type so I can pass in any datatype, whether it be int, string, etc
You need to add a where T : class contstraint, to match the constraint in MyObject.
1

How about an extension method?

public static bool HasAny(this IEnumerable source, Type type) { foreach (object item in source) if (item != null && item.GetType().Equals(type)) return true; return false; } 

Usage:

bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>)); 

Note that if you don't want to have to type out typeof(...) -- i.e., if you basically want your Exist method to only care about objects of type MyObject<T>, I'd go with something like SLaks's answer:

public static bool Exist<T>(this IEnumerable source) { return source.OfType<MyObject<T>>().Any(); } 

Also, SLaks is right that you really can't have a List<MyObject<object>> that's full of anything other than objects of type MyObject<object> or some derived class (and MyObject<datatype1>, etc. do not derive from MyObject<object> -- generics don't work that way).

Another way I might suggest to work around the whole "you can't get the type of a generic class using a System.Type object without using reflection" issue would be this: Make your MyObject<T> implement a non-generic interface, like this:

public interface IMyObject { Type DataType { get; } } public class MyObject<T> : IMyObject<T>, IMyObject { public Type DataType { get { return typeof(T); } } } 

Then your list could be a List<IMyObject> (the non-generic interface) and your Exist method could look like this:

public static bool Exist<T>(this IEnumerable source, Type type) { return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type)); } 

Comments

0

Since they all implement the same interface, instead of casting them to object and calling GetType (which can be expensive) why not add a property to your interface called class name (or something)? Then you can use the linq in order to grab that property. And don't forget using System.Linq

using System.Linq; public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck) { return objects.Any(t => t.ObjectName == typeToCheck.ObjectName); } 

1 Comment

My interface is IMyInterface<T>

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.