[英]C# determining generic type
I have several templated objects that all implement the same interface: 我有几个模板化的对象都实现了相同的接口:
IE IE
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: 我想将这些对象存储在List中...我想我会这样做:
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. 然后我想创建一个函数,它接受一个参数,作为数据类型,以查看我的列表中是否存在使用该数据类型的对象.... sorta无知如何去做。 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>
. 我的界面是
IMyObject<T>
,我的对象是MyObject<T>
。 I have a new class MyObjectManager
which I need to have a List of MyObject<T>
stored within. 我有一个新类
MyObjectManager
,我需要在其中存储一个MyObject<T>
列表。 I need a function to check if a MyObject<T>
exists in that list. 我需要一个函数来检查该列表中是否存在
MyObject<T>
。 The type T
are datatypes which were auto-generated using T4.... POCO classes from my Entity Data Model. 类型
T
是使用来自我的实体数据模型的T4 .... POCO类自动生成的数据类型。
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. 请注意,这需要您在编译时知道
T
If all you have is a System.Type
object at runtime, you'll need to use reflection: 如果您拥有的只是运行时的
System.Type
对象,则需要使用反射:
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>
. 但请注意,
List<MyObject<object>>
无法保存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. 您需要将列表更改为
List<object>
,或使MyObject
实现或继承非泛型类型并使列表包含该类型。
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(...)
-- ie, 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: 请注意,如果您不想输入
typeof(...)
- 也就是说,如果您基本上希望您的Exist
方法只关心MyObject<T>
类型的对象,那么我会选择像SLaks这样的东西。回答:
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). 另外,SLaks是正确的,你真的不能有一个
List<MyObject<object>>
,除了MyObject<object>
类型的MyObject<object>
或者某些派生类(和MyObject<datatype1>
等)之外,其他任何东西都不是派生自MyObject<object>
- 泛型不起作用)。
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: 我可能建议解决整个问题的另一种方法是“你不能使用
System.Type
对象而不使用反射来获取泛型类的类型”问题:将MyObject<T>
实现为非泛型接口,像这样:
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: 然后你的列表可能是
List<IMyObject>
(非泛型接口),你的Exist
方法可能如下所示:
public static bool Exist<T>(this IEnumerable source, Type type) {
return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type));
}
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)? 因为它们都实现了相同的接口,而不是将它们转换为对象并调用GetType(这可能很昂贵)为什么不在你的接口中添加一个名为class name(或者其他东西)的属性? Then you can use the linq in order to grab that property.
然后你可以使用linq来获取该属性。 And don't forget
using System.Linq
不要忘记
using System.Linq
using System.Linq;
public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck)
{
return objects.Any(t => t.ObjectName == typeToCheck.ObjectName);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.