Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# why need struct if class can cover it?

Tags:

c#

struct

Just wondering why we need struct if class can do all struct can and more? put value types in class has no side effect, I think.

EDIT: cannot see any strong reasons to use struct

A struct is similar to a class, with the following key differences:

  • A struct is a value type, whereas a class is a reference type.
  • A struct does not support inheritance (other than implicitly deriving from object).
  • A struct can have all the members a class can, except the following:
  • A parameterless constructor
  • A finalizer
  • Virtual members

A struct is used instead of a class when value type semantics are desirable. Good examples of structs are numeric types, where it is more natural for assignment to copy a value rather than a reference. Because a struct is a value type, each instance does not require instantiation of an object on the heap. This can be important when creating many instances of a type.

like image 600
5YrsLaterDBA Avatar asked Feb 19 '10 21:02

5YrsLaterDBA


People also ask

What do you mean by C?

C is a structured, procedural programming language that has been widely used both for operating systems and applications and that has had a wide following in the academic community. Many versions of UNIX-based operating systems are written in C.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Why is C programming language important?

One of the most significant features of C language is its support for dynamic memory management (DMA). It means that you can utilize and manage the size of the data structure in C during runtime. C also provides several predefined functions to work with memory allocation.

Why is C called a mid level programming language?

C has the features of both assembly level languages i.e low-level languages and higher level languages. So that's why C is generally called as a middle-level Language. The user uses C language for writing an operating system and generates menu driven customer billing system.


2 Answers

Custom value types aren't absolutely necessary - Java does without them, for example. However, they can still be useful.

For example, in Noda Time we're using them pretty extensively, as an efficient way of representing things like instants without the overhead of an object being involved.

I wouldn't say that "class can do all struct can and more" - they behave differently, and should be thought of differently.

like image 190
Jon Skeet Avatar answered Oct 05 '22 09:10

Jon Skeet


Why use a struct when a class works? Because sometimes a class doesn't work.

In addition to the performance reasons mentioned by Reed Copsey (short version: fewer objects that the GC needs to track, allowing the GC to do a better job), there is one place where structures must be used: P/Invoke to functions that require by-value structures or structure members.

For example, suppose you wanted to invoke the CreateProcess() function. Further suppose that you wanted to use a STARTUPINFOEX structure for the lpStartupInfo parameter to CreateProcess().

Well, what's STARTUPINFOEX? This:

typedef struct _STARTUPINFOEX {
    STARTUPINFO                    StartupInfo;
    PPROC_THREAD_ATTRIBUTE_LIST    lpAttributeList;
} STARTUPINFOEX, *LPSTARTUPINFOEX;

Notice that STARTUPINFOEX contains STARTUPINFO as its first member. STARTUPINFO is a structure.

Since classes are reference types, if we declared the corresponding C# type thus:

[StructLayout(LayoutKind.Sequential)]
class STARTUPINFO { /* ... */ }

class STARTUPINFOEX { public STARTUPINFO StartupInfo; /* ... */ }

The corresponding in-memory layout would be wrong, as STARTUPINFOEX.StartupInfo would be a pointer (4 bytes on ILP32 platforms), NOT a structure (as is required, 68 bytes in size on ILP32 platforms).

So, to support invoking arbitrary functions which accept arbitrary structures (which is what P/Invoke is all about), one of two things are necessary:

  1. Fully support value types. This allows C# to declare a value type for STARTUPINFO which will have the correct in-memory layout for marshaling (i.e. struct support, as C# has).

  2. Some alternate syntax within P/Invokeable structures which would inform the runtime marshaler that this member should be laid out as a value type instead of as a pointer.

(2) is a workable solution (and may have been used in J/Direct in Visual J++; I don't remember), but given that proper value types are more flexible, enable a number of performance optimizations not otherwise achievable, and make sensible use within P/Invoke scenarios, it's no surprise that C# supports value types.

like image 22
jonp Avatar answered Oct 05 '22 09:10

jonp