Pat*_*ins 647 .net c# generics
假设我在类或方法中有一个泛型成员,所以:
public class Foo<T>
{
public List<T> Bar { get; set; }
public void Baz()
{
// get type of T
}
}
Run Code Online (Sandbox Code Playgroud)
当我实例化类时,T变为MyTypeObject1,所以类具有通用列表属性:List<MyTypeObject1>.这同样适用于非泛型类中的泛型方法:
public class Foo
{
public void Bar<T>()
{
var baz = new List<T>();
// get type of T
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道,我的类列表包含什么类型的对象.所以调用的list属性Bar或局部变量baz包含什么类型的T?
我做不到Bar[0].GetType(),因为列表可能包含零元素.我该怎么做?
Tam*_*ege 658
如果我理解正确,您的列表与容器类本身具有相同的类型参数.如果是这种情况,那么:
Type typeParameterType = typeof(T);
Run Code Online (Sandbox Code Playgroud)
如果您处于object作为类型参数的幸运情况,请参阅Marc的答案.
Mar*_*ell 507
(注:我假设你知道object或IList或类似的,并且这个名单可以是任何类型的在运行时)
如果你知道它是a List<T>,那么:
Type type = abc.GetType().GetGenericArguments()[0];
Run Code Online (Sandbox Code Playgroud)
另一种选择是查看索引器:
Type type = abc.GetType().GetProperty("Item").PropertyType;
Run Code Online (Sandbox Code Playgroud)
使用新的TypeInfo:
using System.Reflection;
// ...
var type = abc.GetType().GetTypeInfo().GenericTypeArguments[0];
Run Code Online (Sandbox Code Playgroud)
3dG*_*ber 48
使用以下扩展方法,您可以在没有反射的情况下逃脱:
public static Type GetListType<T>(this List<T> _)
{
return typeof(T);
}
Run Code Online (Sandbox Code Playgroud)
或者更一般:
public static Type GetEnumeratedType<T>(this IEnumerable<T> _)
{
return typeof(T);
}
Run Code Online (Sandbox Code Playgroud)
用法:
List<string> list = new List<string> { "a", "b", "c" };
IEnumerable<string> strings = list;
IEnumerable<object> objects = list;
Type listType = list.GetListType(); // string
Type stringsType = strings.GetEnumeratedType(); // string
Type objectsType = objects.GetEnumeratedType(); // BEWARE: object
Run Code Online (Sandbox Code Playgroud)
Rau*_*otz 31
尝试
list.GetType().GetGenericArguments()
Run Code Online (Sandbox Code Playgroud)
小智 14
这对我有用.myList是一些未知的列表.
IEnumerable myEnum = myList as IEnumerable;
Type entryType = myEnum.AsQueryable().ElementType;
Run Code Online (Sandbox Code Playgroud)
如果您不需要整个Type变量并且只想检查类型,则可以轻松创建临时变量并使用is运算符.
T checkType = default(T);
if (checkType is MyClass)
{}
Run Code Online (Sandbox Code Playgroud)
小智 9
您可以将此一个用于通用列表的返回类型:
public string ListType<T>(T value)
{
var valueType = value.GetType().GenericTypeArguments[0].FullName;
return valueType;
}
Run Code Online (Sandbox Code Playgroud)
小智 8
考虑一下:我使用它以相同的方式导出20个类型列表:
private void Generate<T>()
{
T item = (T)Activator.CreateInstance(typeof(T));
((T)item as DemomigrItemList).Initialize();
Type type = ((T)item as DemomigrItemList).AsEnumerable().FirstOrDefault().GetType();
if (type == null) return;
if (type != typeof(account)) //account is listitem in List<account>
{
((T)item as DemomigrItemList).CreateCSV(type);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
GetGenericArgument()必须在实例的基本类型(其类是泛型类myClass<T>)上设置该方法.否则,它返回一个类型[0]
例:
Myclass<T> instance = new Myclass<T>();
Type[] listTypes = typeof(instance).BaseType.GetGenericArguments();
Run Code Online (Sandbox Code Playgroud)
您可以使用以下方法从实现IEnumerable <T>的任何集合类型中获取“ T”类型:
public static Type GetCollectionItemType(Type collectionType)
{
var types = collectionType.GetInterfaces()
.Where(x => x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(IEnumerable<>))
.ToArray();
// Only support collections that implement IEnumerable<T> once.
return types.Length == 1 ? types[0].GetGenericArguments()[0] : null;
}
Run Code Online (Sandbox Code Playgroud)
请注意,它不支持两次实现IEnumerable <T>的集合类型,例如
public class WierdCustomType : IEnumerable<int>, IEnumerable<string> { ... }
Run Code Online (Sandbox Code Playgroud)
我想如果您需要支持此类型,则可以返回一个类型数组。
另外,如果您经常这样做(例如循环执行),则可能还希望按集合类型缓存结果。
我使用此扩展方法来完成类似的操作:
public static string GetFriendlyTypeName(this Type t)
{
var typeName = t.Name.StripStartingWith("`");
var genericArgs = t.GetGenericArguments();
if (genericArgs.Length > 0)
{
typeName += "<";
foreach (var genericArg in genericArgs)
{
typeName += genericArg.GetFriendlyTypeName() + ", ";
}
typeName = typeName.TrimEnd(',', ' ') + ">";
}
return typeName;
}
public static string StripStartingWith(this string s, string stripAfter)
{
if (s == null)
{
return null;
}
var indexOf = s.IndexOf(stripAfter, StringComparison.Ordinal);
if (indexOf > -1)
{
return s.Substring(0, indexOf);
}
return s;
}
Run Code Online (Sandbox Code Playgroud)
您可以这样使用它:
[TestMethod]
public void GetFriendlyTypeName_ShouldHandleReallyComplexTypes()
{
typeof(Dictionary<string, Dictionary<string, object>>).GetFriendlyTypeName()
.ShouldEqual("Dictionary<String, Dictionary<String, Object>>");
}
Run Code Online (Sandbox Code Playgroud)
这并不是您要找的东西,但是对演示所涉及的技术很有帮助。
| 归档时间: |
|
| 查看次数: |
595635 次 |
| 最近记录: |