78

I am curious about the string and primitive types. Article like this says string is primitive type. However second article on MSDN does not list string as primitive type.

However when I ran the code provided in second article, it displays String is not Primitive type.

Can any one guide me on this?

Ram
  • 11,404
  • 15
  • 62
  • 93
  • 4
    You could always try the second article's code sample and discover for yourself. – Mauricio Oct 19 '10 at 06:18
  • I tried the code, it displays String is not primitive type – Ram Oct 19 '10 at 06:24
  • 14
    @kyte: i believe the OP wanted some comments on the fact that two official microsoft pages on MSDN have different opinions on whether string is a primitive type. Telling him to only use one of the sources is not very helpful without valid arguments – Isak Savo Oct 19 '10 at 06:27
  • All the answers make no sense as long as there is no definition of the primitive type in C#. And there is no one agreed upon definition. Some sources tell that primitive types are such types which come by default and that means string would be primitive. Other sources provide no definition and just enumerate the list of primitive types and since the string is not included in that list it can be considered non primitive. So, I would vote to close the question if I would be able to. – some1 here Mar 07 '21 at 19:53

10 Answers10

55

Both articles say that string is NOT a primitive type. Which it is not.

If you compile and run the example code from the second article it would print:

string is not a primitive type.

I think the confusion about this is, that the syntax of of creating a new string is similar to creating value types.

When defining a value type all of these are equal (on a 32 bit system anyway)

System.Int32 a = new System.Int32(5);
System.Int32 a = 5;
int a = 5;

Just like these when creating a reference type string:

System.String s = new System.String(new char[]{'h', 'e', 'l', 'l', 'o'});
System.String s = "hello";
string s = "hello";

Also we can compare strings by value even though they are reference types:

s == "hello";//true

This still does not make string a primitive type.

The accepted answer to this question should give you details on that.

Community
  • 1
  • 1
Fedearne
  • 7,049
  • 4
  • 27
  • 31
  • 4
    If you see the first article, it says Visual Basic .NET defines the following primitive types: which lists : The String reference type, which represents a sequence of Unicode characters and maps to System.String. The default value of the String type is a null reference. – Ram Oct 19 '10 at 06:16
  • 1
    @Ram - yet you've tagged this question C#... there are lots of places where VB uses slightly different interpretations. (clarification; the [vb.net] tag was added later) – Marc Gravell Oct 19 '10 at 06:24
  • @ Marc - Thanks for pointing it out. I have included VB.NET tag. I just want to know if there is any difference between C# and VB.NET primitive types. – Ram Oct 19 '10 at 06:26
  • 5
    @Ram - they are **exactly** the same types, so no actual difference. If VB wants to **call** string primitive, then fine. But that doesn't make it a .NET primitive. – Marc Gravell Oct 19 '10 at 06:27
  • The answer makes no sense as long as there is no definition of the primitive type in C#. And there is no one agreed upon definition. – some1 here Mar 07 '21 at 19:51
52

There is no "Microsoft" definition of what a primitive type is.

There are only definitions of primitive types in a given context.

  • The CLR defines primitive types as being nothing more than:
    • System.Boolean
    • System.Byte
    • System.SByte
    • System.Int16
    • System.UInt16
    • System.Int32
    • System.UInt32
    • System.Int64
    • System.UInt64
    • System.IntPtr
    • System.UIntPtr
    • System.Char
    • System.Double
    • System.Single
  • The VB.NET specification version 10 (in section 7.3) defines "primitive types" as being types that have a keyword alias for the type (thus allowing the usage of that type without importing the System namespace), a way to define instances of that type with a literal; and permitting the use of these types as constants; the primitive types in VB.NET are:
    • System.Byte
    • System.SByte
    • System.UInt16 (UShort)
    • System.Int16 (Short)
    • System.UInt32 (UInteger)
    • System.Int32 (Integer)
    • System.UInt64 (ULong)
    • System.Int64 (Long)
    • System.Single
    • System.Double
    • System.Decimal
    • System.Boolean
    • System.DateTime (Date)
    • System.Char
    • System.String
  • The C# specification (version 4) defines keyword aliases for some types, and also defines way of specifying literals for some values; it also defines, separately, which types are available in constant expressions; the closest concept to "primitive types" that C# has is in section 4.1.4: Simple types. (the word "primitive" is only used twice in the 600 pages document); these primitive types are simply defined as "value types that have a keyword alias in C#" - string is not mentioned in that section:

    • System.SByte (sbyte)
    • System.Byte (byte)
    • System.Int16 (short)
    • System.UInt16 (ushort)
    • System.Int32 (int)
    • System.UInt32 (uint)
    • System.Int64 (long)
    • System.UInt64 (ulong)
    • System.Char (char)
    • System.Single (float)
    • System.Double (double)
    • System.Boolean (bool)
    • System.Decimal (decimal)

You will see that there is only a partial overlap between all of these things; the CLR sees both pointer types as primitive, both VB.NET and C# see decimal as a primitive/simple type, only VB.NET sees DateTime as anything special, both VB.NET and C# have a keyword alias and a literal syntax for strings but only VB.NET specifies String as being a "primitive type", while C# simply has a section of its specification dedicated to System.String...

In conclusion: different contexts have different definitions for what a "primitive type" is. It does not matter - just learn how to use your programming language, there is no sense in fighting and thinking over such polymorphic words. Personally, I wonder why the property Type.IsPrimitive even exists.

As for System.String:

  • CLR: Nothing special, it is just a reference type;
  • VB.NET: It is a primitive type;
  • C#: String is its own very special snowflake;
Jean Hominal
  • 16,518
  • 5
  • 56
  • 90
  • 1
    To the CLR, I don't think `String` is "just another reference type". Strings and arrays are the only objects whose size is not implied by their types. Further, I believe string is the only kind of type for which the run-time will, when loading an assembly, auto-generate instances containing data stored in that assembly. – supercat Jul 11 '14 at 19:32
  • _"value types that have a keyword alias in C#" - string is not mentioned in that section_. Well, string is a reference type after all. – Alexander Gonchiy Aug 10 '15 at 01:28
  • I'm trying to understand the implications of the "IsPrimitive" differences between CLR, VB.NET and C#. For example, if I write code in C# containing a condition based on an object being a primitive type, and my unit test asserts it works as expected for a DateTime (which C# considers not to be primitive). Then I compile a DLL which is referenced by a developer using VB.NET (which considers DateTime to be primitive), will the behaviour of my DLL be different (in other words, is my unit test only worthy in the C# context which is useless)? – Matt Oct 24 '15 at 10:00
  • 2
    @Matt: The `IsPrimitive` function has the same behavior, no matter what .NET language it is called from, and it is the CLR definition. – Jean Hominal Oct 25 '15 at 22:03
  • IMO, This is the better answer. Highlights differences between CLR, C# and VB.Net better. Also states in comments that IsPrimitive is based off of CLR behavior which makes sense and is good to know. – Landon Poch Nov 04 '15 at 02:32
  • Interestingly this piece of code in VB.Net `Dim str As String = "" Console.WriteLine(str.GetType().IsPrimitive)` prints false. But as you are saying string has been mentioned as a primitive type in the documentation of VB.Net which appears contradictory. – RBT Oct 14 '16 at 02:57
9

Change-of-stance Update: No since code doesn't lie

Console.WriteLine(typeof(string).IsPrimitive); => False
Console.WriteLine(typeof(int).IsPrimitive); => True

-----end of update.
But some documentation online seems to treat String as a primitive. I think Yes - based on the following definition of "primitive". (My personal definition would be a type which can't be broken down further into component types. But I guess we're just being 'pedantic' here, it's a non-issue for me mostly.)

all primitive data types in C# are objects in the System namespace. For each data type, a short name, or alias, is provided.

Source: http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx Another article in favor - MSDN Mag article

Summary: I guess the answer depends on your definition of primitive, which is not unambiguously defined. Source: Eric Lippert on another SO thread.

Community
  • 1
  • 1
Gishu
  • 134,492
  • 47
  • 225
  • 308
  • By your definition I guess only the single bit is primitive? ;-) (Int32 is nothing more than 4 bytes stacked together for instance) – Isak Savo Oct 19 '10 at 06:24
  • 1
    that definition doesn't mean that all types in `System` namespace are primitives (i can add types to `System` namespace in my assembly, so they will be primitives?), it just states that all exisiting primitive types can be found in `System` and nowhere else. – max Oct 19 '10 at 06:26
  • @Isak - you can take any guideline to the extreme :) Getting the 3rd byte out of an Int has no individual/specific use in most cases. Getting the FirstName out of a composed Address type does. So the Int would be a primitive to me.. the address won't. – Gishu Oct 19 '10 at 06:31
  • @max - I also included an language defined alias for the type - so String has an alias string. A custom type in the System namespace wouldn't have one AFAIK. – Gishu Oct 19 '10 at 06:32
  • @gishu: yeah I know, I was deliberately taking it to the extreme to make a point. I'd say extracting the third byte of an int is about as common as extracting the third character of a string - I've done both occasionally. I'm giving you +1 for your summary because that's spot on - nobody seems to be able to clearly define what *primitive* means – Isak Savo Oct 19 '10 at 06:46
  • @Isak - I was going for has the 'no independent significance in the 90% case' angle. While I don't have a good definition for primitive at the moment... :D (Hint: while I do not currently have a scathing retort, you check your email periodically for a doozy. - Sheldon Cooper) – Gishu Oct 19 '10 at 06:54
  • // Determine whether the types are primitive datatypes. Console.WriteLine("{0} is a primitive data type: {1}.", Yes, there are so many post says string is primitive typeof(int).Name, typeof(int).IsPrimitive); Console.WriteLine("{0} is a primitive data type: {1}.", typeof(string).Name, typeof(string).IsPrimitive);https://msdn.microsoft.com/en-us/library/system.type.isprimitive(v=vs.110).aspx – Deep Dec 20 '17 at 04:15
  • The CLR defiition of primitive type is very useful as it specifies a a blittable non-structured system type. – ceztko Nov 28 '18 at 11:23
5

.NET defines (from your article):

The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Char, Double, and Single.

So no. Inbuilt and very important: yes, but not a primitive.

VB uses a slightly different definition to the CLI and C# it seems.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
4

Under Microsoft's definition of "primitive", string is not considered a primitive type. On the other hand, Microsoft tends to use terminology without really formulating a clear or consistent definition (e.g. "unmanaged resource"), and one could usefully define "primitive" to include "String", "Array", and "Object", since in their absence there would be no way to define types that could emulate them efficiently.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • Good answer. VB.NET considers `DateTime` to be primitive too, which is somewhat ok according to me. – nawfal Jul 11 '14 at 18:48
3

No, the string is not a primitive type.

However, it has some characteristics common with the primitive types.

The language supports string literals in the code, so that you don't have to explicitly create String instances using the new keyword to get a string object.

There is also support for concatenating strings using the + operator, which the compiler turns into a call to the String.Concat method.

Strings are immutable, which means that it in most situations has value type semantics, just like the primitive types.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • so why isn't it primitive? I mean what characteristic does it *not* have that other primitive types have? – Isak Savo Oct 19 '10 at 06:33
  • I mean you say it's not primitive but then lists stuff that could argue that it should be called primitive.. You never mentioned why it *isn't* a primitive type. (I'm sincerely interested, and I'm not the one who downvoted) – Isak Savo Oct 19 '10 at 06:40
  • @Isak Savo: Primitive types are values that processors can handle natively. The processor has instructions for adding doubles, but not strings. – Guffa Oct 19 '10 at 07:04
1

String is a special primitive type. It is not a value type, but can be considered a primitive type because it can be created by writing literals, eg/ "hello" and it is possible to declare a constant of type string. Having said that, the value of IsPrimitive returns false

Console.WriteLine("hello".GetType().IsPrimitive) // output = False

EDIT: I want to take back my answer here. It is technically not a primitive type, but shares the properties I stated above.

Tim Carter
  • 590
  • 3
  • 9
  • I would suggest that a useful definition of primitive type should include things which, if not explicitly handled by compilers and the runtime, could not be efficiently emulated in user code. By that definition, strings and arrays would be a primitive types since they have special handling which is unlike anything user code could do. – supercat Oct 12 '12 at 21:32
1

In c# the types are primarily defined as two types: value types and primitive types.

First see the definition of primitive types in C#.

On the other hand, all primitive data types in C# are objects in the System namespace. For each data type, a short name, or alias, is provided. For instance, int is the short name for System.Int32 and double is the short form of System.Double.

Now, read this article for the difference: Primitive Types & Value Types

System.String maps to "string", which is a primitive type in the CLI. But in the reality, value types are the ones which go in the stack and not in the heap space.

So, the key is Value types vs Primitive types. By Microsoft's definition of primitive, it is a primitive type, but in a more general sense, its not.

Theraot
  • 31,890
  • 5
  • 57
  • 86
zengr
  • 38,346
  • 37
  • 130
  • 192
-1

String is a reference type. To verify this do F12 on string.

enter image description here

Jeevath
  • 51
  • 1
  • 3
  • 1
    Your answer has nothing to do with the question. So, I downvote it. String being a reference does not mean that it is not a primitive type. – some1 here Mar 07 '21 at 19:55
-3

they are not, because they are sequence of characters