2

I know in VB you can define a UDT like:

Public Type Buffer1
    ProductCode As String
    SerialNumber As String
    Date As Date
End Type

Is it possible to create a User Defined Type in C#? I know that they are used to implement data structures. I have researched and cannot seem to find anything.

lornasw93
  • 182
  • 4
  • 26
  • 3
    you might refer to class? every class can be thought as a user defined type. – David Dec 15 '13 at 15:22
  • 2
    You're looking for classes. – SLaks Dec 15 '13 at 15:23
  • @SLaks: I don't think so. If `Buffer1` is a class, then after `Buffer1 a,b; ... a=b;`, how would one set `b.Date` without setting `a.Date`? If all fields are of value types, `String`, or immutable class types, a .NET struct will allow `a.Date` to be modified independent of `b.Date`, just like the VB6 `Type` the original poster is asking about. Using a class type for such a purpose is a recipe for disaster. – supercat Dec 16 '13 at 04:54
  • @supercat: Yes; he also need to understand reference types. Using structs is just a different disaster. – SLaks Dec 16 '13 at 04:55
  • @SLaks: There are times when each is appropriate. In cases where one would use a `Type` in vb6 to represent something that doesn't contain arrays, a public-field struct will behave as a drop-in replacement. The "problems" with mutable structs all revolve around attempts to use them as something other than a VB6 `Type`; if one only expects a structure type to behave as a VB6 `Type`, and refrains from doing anything with it that one couldn't do with a `Type`, I can't think of any cases in which structs would do anything other than what's expected. – supercat Dec 16 '13 at 05:20
  • @SLaks: I guess my advice for a VB6 programmer would be that if a data type is being used as a replacement for a VB6 `Type`, use a `struct`; if it's supposed to be a replacement for a VB6 Class, use a struct only if the type would be small, has a sensible default value, and would never be mutated except via replacement. Otherwise use class. A VB6 programmer who has a good sense for when to use `Type` versus `Class` should have no trouble with .NET outside the limited ability for structs to encapsulate arrays. – supercat Dec 16 '13 at 05:29

3 Answers3

2

The .NET equivalent of the VB6 Type is a struct with public fields. If what you need is the equivalent of the VB6 type, you should the ignore people who are telling you not to use a mutable struct.

Some people believe all data types should behave like class objects, and since structs with exposed fields behave in ways that class objects cannot they are evil.

In reality, there are times when the equivalent of a VB6 Type can be very useful, and any attempt to achieve such functionality with anything other than an exposed-field or otherwise "mutable" struct will be more cumbersome and yield less performant code than would using a type whose natural semantics precisely match what one is trying to achieve. Note that struct fields should generally be exposed as fields rather than properties, since the whole purpose of a VB6 Type is to serve as an aggregation of data types, rather than an ecapsulation of protected state.

There is, alas, one problem with .NET structure types, which is that unless you declare a structure as an unsafe type, only usable within unsafe code (and not usable in contexts which require being able to run in a Partial Trust environment), arrays within structures cannot achieve the semantics of arrays nor fixed-length strings in a VB6 Type. C# will allow one to declare fixed-sized arrays within a struct using the fixed keyword, but as noted only in conjunction with unsafe. Any other array declarations within a struct will cause a struct to hold an array reference rather than an array. Thus:

struct MyStruct {int n; int[] Arr; }

MyStruct a,b;

a.Arr = new int[4];
a.Arr[0] = 3;
a.n = 1;
b=a; // Copies the value of n, and the array reference in Arr, but not the array contents
b.n = 2;
b.Arr[1] = 2;

After the above code runs, b has its own copy of variable n, so the write to b.n will not affect a.n. Field b.Arr, however, holds a reference to the same array as a.Arr. An assignment directly to field Arr of b could make it point to a different array from a.Arr, but the assignment to b.Arr[1] doesn't actually write to field Arr but instead writes to the array object identified by that field, which is the same object identified by field a.Arr.

In some cases, you can replace what in VB6 would be a fixed-sized array with a simple list of discrete variables. Icky, but workable. Alternatively, if the restrictions associated with fixed arrays aren't a problem, you could use those. Beyond that, there isn't any good way to include arrays within a structure.

supercat
  • 77,689
  • 9
  • 166
  • 211
1

A "User Defined Data Type" from Visual Basic is called a Structure in VB.Net, and a struct in C#.

public struct Buffer1
{
    public string ProductCode;
    public string SerialNumber; 
    public DateTime Date; 
}

Note that unlike the VB6 Type, which always makes all fields public, fields in all .NET types, including structures, default to private.

supercat
  • 77,689
  • 9
  • 166
  • 211
bjnr
  • 3,353
  • 1
  • 18
  • 32
1

C# have classes and structs:

public class Buffer1
{
    string ProductCode;
    string SerialNumber;
    DateTime Date;
}

But if you don't know classes, you must previously read some articles or books about C# (e.g. CLR via C#)

Boris Parfenenkov
  • 3,219
  • 1
  • 25
  • 30