使用反射,我试图找到从给定基类继承的类型集.花了很长时间才弄清楚简单的类型,但是当涉及到泛型时我很难过.
对于这段代码,第一个IsAssignableFrom返回true,但第二个返回false.然而,最后的任务编译得很好.
class class1 { }
class class2 : class1 { }
class generic1<T> { }
class generic2<T> : generic1<T> { }
class Program
{
static void Main(string[] args)
{
Type c1 = typeof(class1);
Type c2 = typeof(class2);
Console.WriteLine("c1.IsAssignableFrom(c2): {0}", c1.IsAssignableFrom(c2));
Type g1 = typeof(generic1<>);
Type g2 = typeof(generic2<>);
Console.WriteLine("g1.IsAssignableFrom(g2): {0}", g1.IsAssignableFrom(g2));
generic1<class1> cc = new generic2<class1>();
}
}
Run Code Online (Sandbox Code Playgroud)
那么如何在运行时确定一个泛型类型定义是否来自另一个?
如何确定对象是否为IEnumerable <T>类型?
码:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
NS.1.Program+<GetInts>d__0
Run Code Online (Sandbox Code Playgroud)
如果我更改GetInts以返回IList,一切正常,输出为:
System.Collections.Generic.List`1[System.Int32]
Run Code Online (Sandbox Code Playgroud)
这会返回false:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.Equals(typeof(IEnumerable<int>)));
}
}
}
Run Code Online (Sandbox Code Playgroud) 如何确定属性是否是一种数组.
例:
public bool IsPropertyAnArray(PropertyInfo property)
{
// return true if type is IList<T>, IEnumerable<T>, ObservableCollection<T>, etc...
}
Run Code Online (Sandbox Code Playgroud) 我试图确定运行时类型是否是某种集合类型.我在下面的工作,但似乎很奇怪,我必须像我所做的那样命名我认为是数组中的集合类型的类型.
在下面的代码中,通用逻辑的原因是因为,在我的应用程序中,我希望所有集合都是通用的.
bool IsCollectionType(Type type)
{
if (!type.GetGenericArguments().Any())
return false;
Type genericTypeDefinition = type.GetGenericTypeDefinition();
var collectionTypes = new[] { typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>), typeof(List<>) };
return collectionTypes.Any(x => x.IsAssignableFrom(genericTypeDefinition));
}
Run Code Online (Sandbox Code Playgroud)
我如何重构此代码以使其更智能或更简单?
开放类型List<>和IEnumerable<>?之间有什么关系吗?
例:
var type1 = typeof(List<>);
var type2 = typeof(IEnumerable<>);
//return false
type2.IsAssignableFrom(type1);
Run Code Online (Sandbox Code Playgroud)
有没有任何方法可以检查两种开放类型之间的关系,或者关系只存在于封闭类型上?
这是我在做什么:
object ReturnMatch(System.Type type)
{
foreach(object obj in myObjects)
{
if (obj == type)
{
return obj;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果 obj 是 的子类type,它将不匹配。但我希望函数以与使用 operator 相同的方式返回is。
我尝试了以下操作,但无法编译:
if (obj is type) // won't compile in C# 2.0
Run Code Online (Sandbox Code Playgroud)
我想出的最佳解决方案是:
if (obj.GetType().Equals(type) || obj.GetType().IsSubclassOf(type))
Run Code Online (Sandbox Code Playgroud)
没有办法使用运算符is使代码更干净吗?
我有:
class MyBase<T1, T2>{}
class MyConcreteBase<T2> : MyBase<ConcreteType1, T2>{}
class MyConcrete1 : MyConcreteBase<ConcreteType2>{}
class MyConcrete2 : MyBase<ConcreteType1, ConcreteType2>{}
Run Code Online (Sandbox Code Playgroud)
我如何得到类型T1和T2如果我有实例MyConcrete1或MyConcrete2或MyConcreteBase或任何其他类型的实例派生自MyBase<T1, T2>
我现在这样做的方式是使用.GetType().BaseTypewhile BaseType.Name.StartsWith("MyBase")然后使用继承链"起床".GetGenericArguments()
它工作正常,但我对它不满意,尤其是.StartsWith("MyBase")部分.
有人有其他建议吗?
我有一个通用的方法:
Func<IEnumerable<T>, bool> CreateFunction<T>()
Run Code Online (Sandbox Code Playgroud)
哪里T可以是任何数量的不同类型.这个方法使用反射做一堆东西,如果T是的话IDictionary,不管字典是什么TKey,TValue我需要执行字典特定的代码.
所以可以调用该方法:
var f = CreateFunction<string>();
var f0 = CreateFunction<SomePocoType>();
var f1 = CreateFunction<IDictionary<string,object>>();
var f2 = CreateFunction<Dictionary<string,object>>();
var f3 = CreateFunction<SomeDerivedDictionaryType<string,object>>();
Run Code Online (Sandbox Code Playgroud)
等等
根据@Andy的答案澄清
最终我想知道是否T从/ implements继承,IDictionary即使它T本身是Dictionary或从该接口派生的其他类型.
if(typeof(T) == typeof(IDictionary<,>)
Run Code Online (Sandbox Code Playgroud)
不起作用,因为T泛型类型不是泛型类型定义.
并且在不知道TKey和TValue(在编译时不知道)的情况下,我不能对运行时我知道的任何具体类型进行比较.
我唯一想到的就是查看类型的名称或者用反射检查它的方法,寻找能让我相信它是字典的方法(即寻找ContainsKey和get_Item).
有没有直接的方法来做出这种决定?
我搜索了这个并找到了: 如何检测类型是否是另一种通用类型
该解决方案的问题在于它期望实现具有相同的类型参数.我想要的是看一个类是否实现了一个带有任何类型参数的接口.
例:
public interface IMapper<in TSource, out TDestination>
{ ... }
public class StringMapper : IMapper<string, StringBuilder>
{ ... }
Console.WriteLine(typeof(IMapper<,>).IsAssignableFrom(typeof(StringMapper)));
Run Code Online (Sandbox Code Playgroud)
我希望这写真,但它写错了.如何检查类是否实现了具有泛型参数的接口?
我想检查以下内容
typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( targetProperty.PropertyType.GetTypeInfo() )
Run Code Online (Sandbox Code Playgroud)
传入的参数IsAssignableFrom是一个IList<Something>.但它正在返回虚假.
以下内容也返回false.
typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( targetProperty.PropertyType.GetTypeInfo().GetGenericTypeDefinition() )
Run Code Online (Sandbox Code Playgroud)
即使以下情况也会返回false.
typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( typeof(IList<>) )
Run Code Online (Sandbox Code Playgroud)
难道后者肯定会回归真实吗?
如果targetProperty.PropertyType可以是任何类型,我怎样才能得到正确的结果?它可以是a List<T>,a ObservableCollection<T>,a ReadOnlyCollection<T>,自定义集合类型等.