1

Is it possible to make a class that is not a struct but is a value type, or is like a value type in that it copies on being passed instead of being passed by reference.

edit:

Sorry about the question having to be edited after being asked.

Also, see this question for more information. Cycle in the struct layout that doesn't exist

Community
  • 1
  • 1
alan2here
  • 3,223
  • 6
  • 37
  • 62
  • Do you mean `Int32`, `Int64` etc.? – mmdemirbas Feb 15 '12 at 16:24
  • It's hard to tell what exactly do you have in mind. In C#, classes are not value types. Why are you asking this? – svick Feb 15 '12 at 16:26
  • Do you mean a class like `System.String`, with value-like semantics? Because, strictly speaking, you declare reference types with `class` and value types with `struct`, by definition. It's impossible to create a value type using the `class` declaration. – phoog Feb 15 '12 at 16:29
  • 2
    I think the term you're looking for is _immutable_. String is an immutable type. There's plenty of questions here on that [topic](http://stackoverflow.com/search?q=c%23+immutable&submit=search). – Marnix van Valen Feb 15 '12 at 16:38
  • 1
    @alan2here In response to your edit: there's no way to make it so a copy is passed rather than a reference. When you pass a string, the reference to the string is passed. The only way to pass a copy of a string is to copy the string yourself and pass a reference to the copy. The only way to make a type that's passed directly rather than by reference is to make a `struct`. ***Why are you trying to do this?*** Answering that question will help us answer yours. – phoog Feb 15 '12 at 16:56
  • @alan2here I edited my answer to say that you cannot create a value type with the `class` keyword. I'm still curious about what you imagine that would look like. What can you do in a `class` declaration that you can't do in a `struct` declaration? Why do you need to be able to do that with a value type? – phoog Feb 15 '12 at 17:40
  • @phoog you can declare a class as abstract but not a struct, in my personal needs I need a type that isn't a reference type, needs to be immutable and provides base implementation for structs that derive from it. –  Jun 06 '22 at 19:12

4 Answers4

6

EDIT 2

As it now seems, you're looking to declare a true value type using the class keyword, which is by definition not possible.


Since you're looking at creating a class with semantics similar to System.String, you should probably decompile System.String. A lot of its magic is hidden away in the CLR, but much of what you will see will help.

For starters, you'll definitely need to overload == and !=, and override Equals() and GetHashCode(). You'll almost certainly want to implement IComparable<T> and IEquatable<T> as well.

Another important aspect of strings is that they are immutable. This is an important part of their value-like behavior, because it guarantees that two equal strings will always be equal. If strings were mutable, it would be possible to modify one of the strings to make it unequal to the other.

I should also point out that while string has semantics that make it seem like a value type, it is of course a reference type, and some aspects of reference semantics are unavoidable.

If you post a little more about why you want to do this, we can offer more specific advice.

EDIT

In response to your edit, it seems you have a misconception about strings. While they do behave like value types in some ways, they are not passed directly by copying their data each time they are passed to a method. The only way to achieve that is to declare a struct. Strings, like all classes, are reference types that can be accessed only by reference; you can only manipulate the reference directly; you can only pass the reference to a method.

phoog
  • 42,068
  • 6
  • 79
  • 117
3

It is possible to design a class that mimics immutable value semantics, almost. System.String falls into that category. Given an instance of a class, the only way to have an instance which is like the first but differs in some way is to construct a new instance based upon the original. To achieve "immutable value semantics, almost", a class should override Object.Equals() and Object.GetHashCode() in such a way that two instances which hold identical data will compare equal to each other and yield the same hashcode.

For classes to mimic mutable value semantics, there would have to be a means of specifying that copying a field of that class type should also copy the object referred to thereby (and if that process requires copying any similarly-declared fields from that object, the objects referred to by those fields would have to be copied as well, etc.) There would be ways of adding support for this into the CLR, but at present no such feature exists.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • Good answer, but as indicated in phoog's answer, you should also override the == and != operators to mimic value semantics. – G-Wiz Apr 01 '12 at 04:04
  • True. It would also have been helpful if there were a way to specify that particular instance methods should not be called "virtually", thus allowing `myString.IsNullOrEmpty()` rather than `String.IsNullOrEmpty(myString)`. If reference types were to have such semantics, one might want to lose the `struct` constraint on `Nullable`, which to be honest I never really liked anyway. – supercat Apr 02 '12 at 13:37
1
public struct Example
{
    public int Property {get;set;}
}

Or, what did you have in mind when you asked for an example?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
0

Although ValueType is the implicit base class for value types, you cannot create a class that inherits from ValueType directly. Instead, individual compilers provide a language keyword or construct (such as struct in C# and Structure…End Structure in Visual Basic) to support the creation of value types.

source: http://msdn.microsoft.com/en-us/library/system.valuetype.aspx

vulkanino
  • 9,074
  • 7
  • 44
  • 71