유형이 원시인지 테스트하는 방법 tagBuilder.Attributes.Add(prop.Name, stringValue); } 나는

유형을 Html 태그로 직렬화하는 코드 블록이 있습니다.

Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
    object propValue = prop.GetValue(myObj, null);
    string stringValue = propValue != null ? propValue.ToString() : String.Empty;
    tagBuilder.Attributes.Add(prop.Name, stringValue);
}

나는 단지 기본 유형과 같은이 작업을 수행 할 제외하고 이것은 좋은 작품 int, double, bool원시적 아니지만처럼 쉽게 직렬화 할 수있는 등, 다른 종류 string. Lists 및 기타 사용자 정의 유형과 같은 다른 모든 것을 무시하고 싶습니다.

아무도 내가 어떻게하는지 제안 할 수 있습니까? 또는 어딘가에 허용하려는 유형을 지정하고 속성 유형을 켜서 허용되는지 확인해야합니까? 조금 지저분하기 때문에 더 깔끔한 방법이 있다면 좋을 것입니다.



답변

당신은 속성을 사용할 수 있습니다 Type.IsPrimitive,하지만 우리는 프리미티브 것을 생각할 수있는 몇 가지 종류가 있기 때문에주의 하시고, 그러나 그들은 예를 들어, 됐소 Decimal하고 String.

편집 1 : 샘플 코드 추가

다음은 샘플 코드입니다.

if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
{
    // Is Primitive, or Decimal, or String
}

편집 2 :@SLaks의 의견도, 어쩌면 당신이 프리미티브로 치료를하고 싶지는 다른 종류가 있습니다. 이 유사 콘텐츠를 하나씩 추가해야한다고 생각합니다 .

편집 3 : IsPrimitive = (부울, 바이트, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double 및 Single), 확인할 다른 기본 형식 (T == typeof (DateTime) ))


답변

난 그냥 비슷한 솔루션을 찾고있는 동안이 질문을 발견하고 사용하여 다음과 같은 접근 방식에 관심이있을 거라고 생각 System.TypeCode하고 System.Convert.

System.TypeCode이외 의 다른 유형으로 매핑 된 모든 유형을 쉽게 직렬화 System.TypeCode.Object할 수 있으므로 다음을 수행 할 수 있습니다.

object PropertyValue = ...
if(Convert.GetTypeCode(PropertyValue) != TypeCode.Object)
{
    string StringValue = Convert.ToString(PropertyValue);
    ...
}

이 방법의 장점은 다른 모든 허용 가능한 기본 형식이 아닌 다른 이름을 지정할 필요가 없다는 것입니다. IConvertible을 구현하는 모든 유형을 처리하기 위해 위의 코드를 약간 수정할 수도 있습니다.


답변

우리는 ORM에서 다음과 같이합니다.

Type t;
bool isPrimitiveType = t.IsPrimitive || t.IsValueType || (t == typeof(string));

나는 사용하는 IsValueType것이 최선의 선택이 아니라는 것을 알고 있지만 (너무 복잡한 구조체를 가질 수는 있지만) 99 %의 경우 작동합니다 (Nullables 포함).


답변

@Ronnie Overby 응답 및 @jonathanconway 의견에서 Nullable에 작동하고 사용자 구조체를 제외시키는이 방법을 작성했습니다.

public static bool IsSimpleType(Type type)
{
    return
        type.IsPrimitive ||
        new Type[] {
            typeof(string),
            typeof(decimal),
            typeof(DateTime),
            typeof(DateTimeOffset),
            typeof(TimeSpan),
            typeof(Guid)
        }.Contains(type) ||
        type.IsEnum ||
        Convert.GetTypeCode(type) != TypeCode.Object ||
        (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0]))
        ;
}

다음 TestCase로 :

struct TestStruct
{
    public string Prop1;
    public int Prop2;
}

class TestClass1
{
    public string Prop1;
    public int Prop2;
}

enum TestEnum { TheValue }

[Test]
public void Test1()
{
    Assert.IsTrue(IsSimpleType(typeof(TestEnum)));
    Assert.IsTrue(IsSimpleType(typeof(string)));
    Assert.IsTrue(IsSimpleType(typeof(char)));
    Assert.IsTrue(IsSimpleType(typeof(Guid)));

    Assert.IsTrue(IsSimpleType(typeof(bool)));
    Assert.IsTrue(IsSimpleType(typeof(byte)));
    Assert.IsTrue(IsSimpleType(typeof(short)));
    Assert.IsTrue(IsSimpleType(typeof(int)));
    Assert.IsTrue(IsSimpleType(typeof(long)));
    Assert.IsTrue(IsSimpleType(typeof(float)));
    Assert.IsTrue(IsSimpleType(typeof(double)));
    Assert.IsTrue(IsSimpleType(typeof(decimal)));

    Assert.IsTrue(IsSimpleType(typeof(sbyte)));
    Assert.IsTrue(IsSimpleType(typeof(ushort)));
    Assert.IsTrue(IsSimpleType(typeof(uint)));
    Assert.IsTrue(IsSimpleType(typeof(ulong)));

    Assert.IsTrue(IsSimpleType(typeof(DateTime)));
    Assert.IsTrue(IsSimpleType(typeof(DateTimeOffset)));
    Assert.IsTrue(IsSimpleType(typeof(TimeSpan)));

    Assert.IsFalse(IsSimpleType(typeof(TestStruct)));
    Assert.IsFalse(IsSimpleType(typeof(TestClass1)));

    Assert.IsTrue(IsSimpleType(typeof(TestEnum?)));
    Assert.IsTrue(IsSimpleType(typeof(char?)));
    Assert.IsTrue(IsSimpleType(typeof(Guid?)));

    Assert.IsTrue(IsSimpleType(typeof(bool?)));
    Assert.IsTrue(IsSimpleType(typeof(byte?)));
    Assert.IsTrue(IsSimpleType(typeof(short?)));
    Assert.IsTrue(IsSimpleType(typeof(int?)));
    Assert.IsTrue(IsSimpleType(typeof(long?)));
    Assert.IsTrue(IsSimpleType(typeof(float?)));
    Assert.IsTrue(IsSimpleType(typeof(double?)));
    Assert.IsTrue(IsSimpleType(typeof(decimal?)));

    Assert.IsTrue(IsSimpleType(typeof(sbyte?)));
    Assert.IsTrue(IsSimpleType(typeof(ushort?)));
    Assert.IsTrue(IsSimpleType(typeof(uint?)));
    Assert.IsTrue(IsSimpleType(typeof(ulong?)));

    Assert.IsTrue(IsSimpleType(typeof(DateTime?)));
    Assert.IsTrue(IsSimpleType(typeof(DateTimeOffset?)));
    Assert.IsTrue(IsSimpleType(typeof(TimeSpan?)));

    Assert.IsFalse(IsSimpleType(typeof(TestStruct?)));
}


답변

내가 한 방법은 다음과 같습니다.

   static class PrimitiveTypes
   {
       public static readonly Type[] List;

       static PrimitiveTypes()
       {
           var types = new[]
                          {
                              typeof (Enum),
                              typeof (String),
                              typeof (Char),
                              typeof (Guid),

                              typeof (Boolean),
                              typeof (Byte),
                              typeof (Int16),
                              typeof (Int32),
                              typeof (Int64),
                              typeof (Single),
                              typeof (Double),
                              typeof (Decimal),

                              typeof (SByte),
                              typeof (UInt16),
                              typeof (UInt32),
                              typeof (UInt64),

                              typeof (DateTime),
                              typeof (DateTimeOffset),
                              typeof (TimeSpan),
                          };


           var nullTypes = from t in types
                           where t.IsValueType
                           select typeof (Nullable<>).MakeGenericType(t);

           List = types.Concat(nullTypes).ToArray();
       }

       public static bool Test(Type type)
       {
           if (List.Any(x => x.IsAssignableFrom(type)))
               return true;

           var nut = Nullable.GetUnderlyingType(type);
           return nut != null && nut.IsEnum;
       }
   }


답변

또한 좋은 가능성 :

private static bool IsPrimitiveType(Type type)
{
    return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}


답변

다음과 같은 함수 서명이 있다고 가정합니다.

void foo<T>() 

값 형식 만 허용하도록 일반 제약 조건을 추가 할 수 있습니다.

void foo<T>() where T : struct

이것은 T에 대한 기본 유형뿐만 아니라 모든 값 유형을 허용합니다.