유형이 "단순"유형인지 어떻게 알 수 있습니까? 즉, 단일 값을 보유합니다.
typeof(string).IsPrimitive == false
typeof(int).IsPrimitive == true
typeof(MyClass).IsClass == true
typeof(string).IsClass == true
typeof(string).IsByRef == false
typeof(MyClass).IsByRef == true // correction: should be false (see comments below)
T의 새 인스턴스를 인스턴스화하는 메서드가 있으며 "복잡한"클래스 인 경우 소스 데이터 값 집합에서 속성을 채 웁니다.
(a) T가 단순 유형 (예 : 문자열 또는 int 또는 기타 유사한 것)이면 소스 데이터에서 T 로의 빠른 변환이 수행됩니다.
(b) T가 클래스 인 경우 (문자열과 같은 단순한 것은 아님) Activator.CreateInstance를 사용하고 필드를 채우기 위해 약간의 반사를 수행합니다.
방법 (a) 또는 방법 (b)를 사용해야하는지 빠르고 간단한 방법이 있습니까? 이 논리는 형식 인수로 T를 사용하는 제네릭 메서드 내에서 사용됩니다.
문자열은 아마도 특별한 경우 일 것입니다.
내가 할 것 같아 .....
bool IsSimple(Type type)
{
return type.IsPrimitive
|| type.Equals(typeof(string));
}
편집하다:
때로는 열거 형 및 소수와 같은 더 많은 경우를 다루어야합니다. 열거 형은 C #에서 특별한 유형의 유형입니다. 소수는 다른 것과 같은 구조체입니다. 구조체의 문제점은 복잡 할 수도 있고 사용자 정의 유형일 수도 있고 숫자 일 수도 있다는 것입니다. 따라서 차별화 할 기회를 아는 것 외에는 다른 기회가 없습니다.
bool IsSimple(Type type)
{
return type.IsPrimitive
|| type.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal));
}
nullable 대응 물을 처리하는 것도 약간 까다 롭습니다. nullable 자체는 구조체입니다.
bool IsSimple(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
return IsSimple(type.GetGenericArguments()[0]);
}
return type.IsPrimitive
|| type.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal));
}
테스트:
Assert.IsTrue(IsSimple(typeof(string)));
Assert.IsTrue(IsSimple(typeof(int)));
Assert.IsTrue(IsSimple(typeof(decimal)));
Assert.IsTrue(IsSimple(typeof(float)));
Assert.IsTrue(IsSimple(typeof(StringComparison))); // enum
Assert.IsTrue(IsSimple(typeof(int?)));
Assert.IsTrue(IsSimple(typeof(decimal?)));
Assert.IsTrue(IsSimple(typeof(StringComparison?)));
Assert.IsFalse(IsSimple(typeof(object)));
Assert.IsFalse(IsSimple(typeof(Point))); // struct in System.Drawing
Assert.IsFalse(IsSimple(typeof(Point?)));
Assert.IsFalse(IsSimple(typeof(StringBuilder))); // reference type
.NET Core 참고 사항
DucoJ가 그의 답변 에서 지적했듯이 사용 된 메서드 중 일부는 Type
.NET 코어 의 클래스 에서 더 이상 사용할 수 없습니다.
수정 된 코드
bool IsSimple(Type type)
{
var typeInfo = type.GetTypeInfo();
if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
return IsSimple(typeInfo.GetGenericArguments()[0]);
}
return typeInfo.IsPrimitive
|| typeInfo.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal));
}
Stefan Steinegger 답변 외에도 .NET Core에서 .IsPrimitive 등은 더 이상 Type의 구성원이 아니며 이제는 TypeInfo의 구성원입니다. 따라서 그의 솔루션은 다음과 같습니다.
bool IsSimple(TypeInfo type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
return IsSimple((type.GetGenericArguments()[0]).GetTypeInfo());
}
return type.IsPrimitive
|| type.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal));
}
프리미티브보다 더 일반적인 유형이 있으며 ValueType은 enums, decimal 및 기타 ValueType 과 같은 프리미티브보다 훨씬 더 많이 포함합니다 . 아래는 귀하의 요구에 맞는 복잡한 유형을 식별하기 위해 작성한 함수입니다.
public static bool IsComplex(Type typeIn)
{
if (typeIn.IsSubclassOf(typeof(System.ValueType)) || typeIn.Equals(typeof(string))) //|| typeIn.IsPrimitive
return false;
else
return true;
}
정말 오래된 스레드를 되살려 서 죄송합니다.하지만 여전히 Google의 웹 검색에서 높은 순위를 차지하고 있으므로보다 직접적이고 효과적인 솔루션을 추가하고 싶습니다.
if(System.Type.GetTypeCode(typeof(int)) == TypeCode.Object) {
// Do what you will...
}
중요하지 않을 수도 있지만 몇 가지 경우를 생략하는 것 같습니다.
- 변환이있는 복합 유형
- 매개 변수없는 생성자가없는 값 유형. 아래 예 :
아마 더 많 겠지만 지나치게 제한적인 방식으로 문제 공간을 분할하고 있다고 생각합니다.
public class Person {
private string _name;
private int _age;
public Person(string name, int age) {_name = name; _age = age;}
// Remainder of value implementation
}
Strings aren't primitives, if I recall correctly. even though there is a keyword for it, a string is an object. Your call to IsPrimitive will accurately tell you if something is a primitive.
Modified Mauser's answer a little bit added a method to check whether a property is an collection.
public static class TypeExtensions { public static bool IsComplex(this Type type) { return !type.IsValueType && type != typeof(string); } public static bool IsCollection(this Type type) { var collectionTypeName = typeof(ICollection<>).Name; return type.Name == collectionTypeName || type.GetInterface(collectionTypeName) != null; } }
Here inside IsCollection(..) we can even keep IEnumerable, but string also inherit IEnumerable. so if you are using IEnumerable, add a check for string also!
public static class TypeExtensions
{
public static bool IsComplex(this Type type)
{
return !type.IsValueType && type != typeof(string);
}
public static bool IsCustomComplex(this Type type)
{
var elementType = type.GetCustomElementType();
return elementType != null && elementType.IsComplex();
}
public static Type GetCustomElementType(this Type type, object value)
{
return value != null
? value.GetType().GetCustomElementType()
: type.GetCustomElementType();
}
public static Type GetCustomElementType(this Type type)
{
return type.IsCollection()
? type.IsArray
? type.GetElementType()
: type.GetGenericArguments()[0]
: type;
}
public static bool IsCustomComplex(this Type type, object value)
{
return value != null
? value.GetType().IsCustomComplex()
: type.IsCustomComplex();
}
public static bool IsCollection(this Type type)
{
var collectionTypeName = typeof(IEnumerable<>).Name;
return (type.Name == collectionTypeName || type.GetInterface(typeof(IEnumerable<>).Name) != null ||
type.IsArray) && type != typeof(string);
}
public static bool HasDefaultConstructor(this Type type)
{
return type.IsValueType || type.GetConstructor(Type.EmptyTypes) != null;
}
}
'Programing' 카테고리의 다른 글
Angular 2 라우터 이벤트 리스너 (0) | 2020.12.11 |
---|---|
CURL을 통해 모든 기기에 Firebase 알림을 어떻게 보내나요? (0) | 2020.12.11 |
SICP에서 Exercise 1.6에 대한 설명은 무엇입니까? (0) | 2020.12.11 |
ASP.NET MVC 2 용 사용자 지정 멤버 자격 공급자는 어떻게 만듭니 까? (0) | 2020.12.11 |
실수로 체크 아웃 한 후 변경 사항을 되 찾으시겠습니까? (0) | 2020.12.11 |