Programing

유형이 "단순"유형인지 어떻게 알 수 있습니까?

lottogame 2020. 12. 11. 07:39
반응형

유형이 "단순"유형인지 어떻게 알 수 있습니까? 즉, 단일 값을 보유합니다.


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...
}

중요하지 않을 수도 있지만 몇 가지 경우를 생략하는 것 같습니다.

  1. 변환이있는 복합 유형
  2. 매개 변수없는 생성자가없는 값 유형. 아래 예 :

아마 더 많 겠지만 지나치게 제한적인 방식으로 문제 공간을 분할하고 있다고 생각합니다.

 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;
        }

    }

참고URL : https://stackoverflow.com/questions/863881/how-do-i-tell-if-a-type-is-a-simple-type-i-e-holds-a-single-value

반응형