C #에서 수업이 일반 유형인지 테스트
수업가 제네릭 유형인지 테스트하고 싶습니다. 나는 성공하지 않고 다음을 시도했다.
public bool Test()
{
List<int> list = new List<int>();
return list.GetType() == typeof(List<>);
}
내가 뭘 잘못하고 있고이 테스트를 어떻게 수행합니까?
제네릭 형식의 인스턴스인지 확인 후 수행하십시오.
return list.GetType().IsGenericType;
이것이 일반인지 확인 광고입니다 List<T>.
return list.GetType().GetGenericTypeDefinition() == typeof(List<>);
Jon이 지적했듯이 동일한 유형의 동등성을 확인합니다. 리턴 false은 반드시 list is List<T>리턴을 의미합니다 false(즉, 오브젝트를 List<T>변수에 수 없음 ).
유형이 제네릭인지 여부를 알고 싶지는 않습니다. 인수를 모른 채 특정 제네릭 유형의 인스턴스인지 알고 싶다고 가정합니다.
불행히도 매우 간단하지 않습니다. 제네릭 형식이 클래스 인 경우 (나쁜 경우) 그렇게 나쁘지는 않지만 인터페이스가 더 어렵습니다. 클래스 코드는 다음과 가변됩니다.
using System;
using System.Collections.Generic;
using System.Reflection;
class Test
{
static bool IsInstanceOfGenericType(Type genericType, object instance)
{
Type type = instance.GetType();
while (type != null)
{
if (type.IsGenericType &&
type.GetGenericTypeDefinition() == genericType)
{
return true;
}
type = type.BaseType;
}
return false;
}
static void Main(string[] args)
{
// True
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new List<string>()));
// False
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new string[0]));
// True
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new SubList()));
// True
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new SubList<int>()));
}
class SubList : List<string>
{
}
class SubList<T> : List<T>
{
}
}
편집 : 의견에서 언급했듯이 인터페이스에서 작동 할 수 있습니다.
foreach (var i in type.GetInterfaces())
{
if (i.IsGenericType && i.GetGenericTypeDefinition() == genericType)
{
return true;
}
}
나는 이것에 어색한 사례가 실패 할 수 없다는 것을 의심 할 수 없습니다.
동적 해법을 사용하여 더 짧은 코드를 사용할 수 있습니다. 순수한 반사보다 느릴 수 있습니다.
public static class Extension
{
public static bool IsGenericList(this object o)
{
return IsGeneric((dynamic)o);
}
public static bool IsGeneric<T>(List<T> o)
{
return true;
}
public static bool IsGeneric( object o)
{
return false;
}
}
var l = new List<int>();
l.IsGenericList().Should().BeTrue();
var o = new object();
o.IsGenericList().Should().BeFalse();
다음은 제네릭 형식 검사의 가장 일반적인 경우 다루는 가장 좋아하는 두 가지 확장 방법입니다.
와 일하다 :
- 다중 (일반) 인터페이스
- 여러 (일반) 기본 클래스
true를 반환하면 특정 제네릭 형식을 '아웃'하는 문자 참조가 있습니다.
public static bool IsOfGenericType(this Type typeToCheck, Type genericType) { Type concreteType; return typeToCheck.IsOfGenericType(genericType, out concreteType); } public static bool IsOfGenericType(this Type typeToCheck, Type genericType, out Type concreteGenericType) { while (true) { concreteGenericType = null; if (genericType == null) throw new ArgumentNullException(nameof(genericType)); if (!genericType.IsGenericTypeDefinition) throw new ArgumentException("The definition needs to be a GenericTypeDefinition", nameof(genericType)); if (typeToCheck == null || typeToCheck == typeof(object)) return false; if (typeToCheck == genericType) { concreteGenericType = typeToCheck; return true; } if ((typeToCheck.IsGenericType ? typeToCheck.GetGenericTypeDefinition() : typeToCheck) == genericType) { concreteGenericType = typeToCheck; return true; } if (genericType.IsInterface) foreach (var i in typeToCheck.GetInterfaces()) if (i.IsOfGenericType(genericType, out concreteGenericType)) return true; typeToCheck = typeToCheck.BaseType; } }
다음은 (기본) 기능을 기본 테스트입니다.
[Test]
public void SimpleGenericInterfaces()
{
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IEnumerable<>)));
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IQueryable<>)));
Type concreteType;
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IEnumerable<>), out concreteType));
Assert.AreEqual(typeof(IEnumerable<string>), concreteType);
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IQueryable<>), out concreteType));
Assert.AreEqual(typeof(IQueryable<string>), concreteType);
}
return list.GetType().IsGenericType;
참고 URL : https://stackoverflow.com/questions/982487/testing-if-object-is-of-generic-type-in-c-sharp
'IT' 카테고리의 다른 글
| Datagridview의 버튼 열에서 클릭 이벤트를 처리하는 방법은 무엇입니까? (0) | 2020.07.08 |
|---|---|
| Windows에서 2 개의 이진 파일을 비교하는 도구 (0) | 2020.07.08 |
| spark에서 rdd 객체를 데이터 프레임으로 변환하는 방법 (0) | 2020.07.08 |
| 제출 버튼을 누른 MVC (0) | 2020.07.08 |
| 오류 : Java Virtual Machine Mac OSX Mavericks를 작성할 수 없습니다. (0) | 2020.07.08 |