Jak sprawdzić czy typ jest prymitywny
Mam blok kodu, który serializuje typ do znacznika 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);
}
To działa świetnie, tylko chcę, żeby to robił tylko dla prymitywnych typów, jak int
, double
, bool
itd, i inne typy, które nie są prymitywne, ale można je łatwo serializować jak string
. Chcę, aby zignorował Wszystko inne, takie jak listy i inne niestandardowe typy.
12 answers
Możesz użyć właściwości Type.IsPrimitive
, ale bądź ostrożny, ponieważ istnieją pewne typy, które możemy uznać za prymitywne, ale nie są, na przykład Decimal
i String
.
Edytuj 1: Dodano przykładowy kod
Oto przykładowy kod:
if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
{
// Is Primitive, or Decimal, or String
}
Edit 2: as @SLaks comments, there are other types that maybe want to treat as primitives, too. Myślę, że będziesz musiał dodać te wariacje jeden po drugim.
Edytuj 3: IsPrimitive = (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single), Anther-Like type to check (t = = typeof (DateTime))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:19
Właśnie znalazłem to pytanie szukając podobnego rozwiązania i pomyślałem, że może zainteresować Cię następujące podejście przy użyciu System.TypeCode
i System.Convert
.
Łatwo jest serializować dowolny typ, który jest odwzorowany na System.TypeCode
inny niż System.TypeCode.Object
, więc możesz to zrobić:
object PropertyValue = ...
if(Convert.GetTypeCode(PropertyValue) != TypeCode.Object)
{
string StringValue = Convert.ToString(PropertyValue);
...
}
Zaletą tego podejścia jest to, że nie musisz wymieniać wszystkich innych akceptowalnych nie-prymitywnych typów. Możesz również nieznacznie zmodyfikować powyższy kod, aby obsługiwał każdy typ, który implementuje IConvertible.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-18 23:31:53
Robimy to tak w naszym ORM:
Type t;
bool isPrimitiveType = t.IsPrimitive || t.IsValueType || (t == typeof(string));
Wiem, że użycie IsValueType
nie jest najlepszą opcją (możesz mieć własne bardzo złożone struktury), ale działa w 99% przypadków (i zawiera Nullables).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 02:17:59
From @ Ronnie Overby response and @ jonathanconway comment, I wrote this method that works for Nullable, and exclude user structs.
public static bool IsSimpleType(Type type)
{
return
type.IsPrimitive ||
new Type[] {
typeof(Enum),
typeof(String),
typeof(Decimal),
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
}.Contains(type) ||
Convert.GetTypeCode(type) != TypeCode.Object ||
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0]))
;
}
Z następującym testem:
struct TestStruct
{
public string Prop1;
public int Prop2;
}
class TestClass1
{
public string Prop1;
public int Prop2;
}
[Test]
public void Test1()
{
Assert.IsTrue(IsSimpleType(typeof(Enum)));
Assert.IsTrue(IsSimpleType(typeof(String)));
Assert.IsTrue(IsSimpleType(typeof(Char)));
Assert.IsTrue(IsSimpleType(typeof(Guid)));
Assert.IsTrue(IsSimpleType(typeof(Boolean)));
Assert.IsTrue(IsSimpleType(typeof(Byte)));
Assert.IsTrue(IsSimpleType(typeof(Int16)));
Assert.IsTrue(IsSimpleType(typeof(Int32)));
Assert.IsTrue(IsSimpleType(typeof(Int64)));
Assert.IsTrue(IsSimpleType(typeof(Single)));
Assert.IsTrue(IsSimpleType(typeof(Double)));
Assert.IsTrue(IsSimpleType(typeof(Decimal)));
Assert.IsTrue(IsSimpleType(typeof(SByte)));
Assert.IsTrue(IsSimpleType(typeof(UInt16)));
Assert.IsTrue(IsSimpleType(typeof(UInt32)));
Assert.IsTrue(IsSimpleType(typeof(UInt64)));
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(Nullable<Char>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Guid>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Boolean>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Byte>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Int16>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Int32>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Int64>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Single>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Double>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<Decimal>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<SByte>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<UInt16>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<UInt32>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<UInt64>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<DateTime>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<DateTimeOffset>)));
Assert.IsTrue(IsSimpleType(typeof(Nullable<TimeSpan>)));
Assert.IsFalse(IsSimpleType(typeof(Nullable<TestStruct>)));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-01 17:47:01
Oto Jak to zrobiłem.
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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 20:50:06
Również dobra możliwość:
private static bool IsPrimitiveType(Type type)
{
return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 09:50:28
Zakładając, że masz taką sygnaturę funkcji:
void foo<T>()
Możesz dodać ogólne Ograniczenie, aby zezwolić tylko na typy wartości:
void foo<T>() where T : struct
Zauważ, że pozwala to nie tylko na typy prymitywne dla T, ale na każdy typ wartości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-14 15:04:27
Miałem potrzebę serializacji typów w celu eksportowania ich do XML. Aby to zrobić, iterowałem przez obiekt i wybrałem pola, które były prymitywne, enum, typy wartości lub serializowalne. To wynik mojego zapytania:
Type contextType = context.GetType();
var props = (from property in contextType.GetProperties()
let name = property.Name
let type = property.PropertyType
let value = property.GetValue(context,
(BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public),
null, null, null)
where (type.IsPrimitive || type.IsEnum || type.IsValueType || type.IsSerializable)
select new { Name = name, Value = value});
Użyłem LINQ do iteracji typów, a następnie uzyskać ich nazwę i wartość do przechowywania w tabeli symboli. Klucz znajduje się w klauzuli "gdzie", którą wybrałem do refleksji. Wybrałem prymitywne, wyliczane, typy wartości i typy serializowalne. To pozwoliło aby ciągi i Obiekty DateTime przeszły tak, jak oczekiwałem.
Zdrówko!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-18 14:55:23
To jest to, co mam w mojej bibliotece. Komentarze są mile widziane.
Sprawdzam najpierw IsValueType, ponieważ obsługuje większość typów, a następnie String, ponieważ jest drugim najczęściej używanym. Nie mogę myśleć o prymitywie, który nie jest typem wartości, więc nie wiem, czy ta noga if kiedykolwiek zostanie uderzona.
Public Shared Function IsPersistable(Type As System.Type) As Boolean
With TypeInformation.UnderlyingType(Type)
Return .IsValueType OrElse Type = GetType(String) OrElse .IsPrimitive
End With
End Function
Public Shared Function IsNullable(ByVal Type As System.Type) As Boolean
Return (Type.IsGenericType) AndAlso (Type.GetGenericTypeDefinition() Is GetType(Nullable(Of )))
End Function
Public Shared Function UnderlyingType(ByVal Type As System.Type) As System.Type
If IsNullable(Type) Then
Return Nullable.GetUnderlyingType(Type)
Else
Return Type
End If
End Function
Wtedy mogę go użyć w ten sposób:
Public Shared Function PersistableProperties(Item As System.Type) As IEnumerable(Of System.Reflection.PropertyInfo)
Return From PropertyInfo In Item.GetProperties()
Where PropertyInfo.CanWrite AndAlso (IsPersistable(PropertyInfo.PropertyType))
Select PropertyInfo
End Function
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-22 16:38:33
Chcę się podzielić moim rozwiązaniem. Może komuś się przyda.
public static bool IsPrimitiveType(Type fieldType)
{
return fieldType.IsPrimitive || fieldType.Namespace.Equals("System");
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-27 08:07:25
public static bool IsPrimitiveType(object myObject)
{
var myType = myObject.GetType();
return myType.IsPrimitive || myType.Namespace == null || myType.Namespace.Equals("System");
}
Nie zapomnij sprawdzić NULL przestrzeni nazw, ponieważ obiekty anonimowe nie mają przypisanej przestrzeni nazw
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-14 21:20:58
Oto kolejna realna opcja.
public static bool CanDirectlyCompare(Type type)
{
return typeof(IComparable).IsAssignableFrom(type) || type.IsPrimitive || type.IsValueType;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-09 22:39:51