Custom primitives in C#? - c#

Apart from the questionable usefulness of this, I'd like to ask if it is possible to do something along these lines.
class MyPrimitive {
String value;
public String Value {
get { return value; }
set { this.value = value; }
}
}
// Instead of doing this...
MyPrimitive a = new MyPrimitive();
a.Value = "test";
String b = a.Value;
// Isn't there a way to do something like this?
MyPrimitive a = "test";
String b = a;
I like to wrap primitive types into custom classes using a property to make the get and set method perform other things, like validation.
Since I'm doing this quite often I thought that it'd be nice to also have a simpler syntax, like for the standard primitives.
Still, I suspect that this not only isn't feasible but could also be conceptually wrong.
Any insights would be most welcome, thanks.

Use a value type (struct) and give it an implicit conversion operator from the type you want on the right hand side of assignment.
struct MyPrimitive
{
private readonly string value;
public MyPrimitive(string value)
{
this.value = value;
}
public string Value { get { return value; } }
public static implicit operator MyPrimitive(string s)
{
return new MyPrimitive(s);
}
public static implicit operator string(MyPrimitive p)
{
return p.Value;
}
}
EDIT: Made the struct immutable because Marc Gravell is absolutely right.

You could use implicit casting. It's not recommended, but:
public static implicit operator string(MyString a) {
return a.Value;
}
public static implicit operator MyString(string a) {
return new MyString { value = a; }
}
Again, bad practice.

Related

Ambiguous implicit user defined conversions in .NET

I recently wrote a couple of structs in .NET, to which I then added implicit conversion operators
Example:
public struct Alpha
{
internal string value;
public static implicit operator Alpha(Beta b)
{
return new Alpha() { value = b.value };
}
public static implicit operator Beta(Alpha a)
{
return new Beta() { value = a.value };
}
}
public struct Beta
{
internal string value;
public static implicit operator Alpha(Beta b)
{
return new Alpha() { value = b.value };
}
public static implicit operator Beta(Alpha a)
{
return new Beta() { value = a.value };
}
}
Test:
Alpha a = default(Alpha);
Beta b = a;
// Ambiguous user defined conversions 'Alpha.implicit operator Beta(Alpha)' and 'Beta.implicit operator Beta(Alpha)' when converting from 'Alpha' to 'Beta'
I would like to know what the rules / best practices are surrounding implicit conversion in C#?
Note to self: My gut feeling is that types should not return objects of another type through implicit conversion? i.e. Beta should not return Alpha via implicit conversion, and vice-versa, however, Beta should return Beta, and Alpha should return Alpha
Example (fixed):
public struct Alpha
{
internal string value;
public static implicit operator Alpha(Beta b)
{
return new Alpha() { value = b.value };
}
}
public struct Beta
{
internal string value;
public static implicit operator Beta(Alpha a)
{
return new Beta() { value = a.value };
}
}
Is my assumption correct?
You have a Alpha(Beta x) defined in both classes, thus it is ambiguous which one should be used. Allow each class to handle only the conversion to itself. In other words, struct Alpha implements Alpha(Beta b) because it best knows how to create an instance of itself. Also, I would consider implementing explicit conversions instead of implicit. It can sometimes cause bugs or unexpected conversions accidentally, and when dealing with complex classes are often "lossy" conversions.
public struct Alpha
{
internal string value;
public static implicit operator Alpha(Beta b)
{
return new Alpha() { value = b.value };
}
}
public struct Beta
{
internal string value;
public static implicit operator Beta(Alpha a)
{
return new Beta() { value = a.value };
}
}
The only time you'd likely implement "both ways" in a single class, is if the other class has no knowledge of your new class. This is the more common scenario when you want to support conversion to-from a pre-existing class/struct such as supporting conversion to-from a framework type:
public struct Alpha
{
internal string value;
public static implicit operator Alpha(string b)
{
return new Alpha() { value = b };
}
public static implicit operator string(Alpha a)
{
return a.value;
}
}
No, your assumpion is not correct (even though you wrote working code thanks to it). The problem in your code is that you have defined the same conversion operators in both classes, this is why they are ambiguous; the compiler cannot decide which one to use.
You can read more in section 6.4.3 (Evaluation of user-defined conversions) of the C# 4.0 Language Specification.

Is there any way to implicitly construct a type in C#?

I read of a useful trick about how you can avoid using the wrong domain data in your code by creating a data type for each domain type you're using. By doing this the compiler will prevent you from accidentally mixing your types.
For example, defining these:
public struct Meter
{
public int Value;
public Meter(int value)
{
this.Value = value;
}
}
public struct Second
{
public int Value;
public Second(int value)
{
this.Value = value;
}
}
allows me to not mix up meters and seconds because they're separate data types. This is great and I can see how useful it can be. I'm aware you'd still need to define operator overloads to handle any kind of arithmetic with these types, but I'm leaving that out for simplicity.
The problem I'm having with this approach is that in order to use these types I need to use the full constructor every time, like this:
Meter distance = new Meter(5);
Is there any way in C# I can use the same mode of construction that a System.Int32 uses, like this:
Meter distance = 5;
I tried creating an implicit conversion but it seems this would need to be part of the Int32 type, not my custom types. I can't add an Extension Method to Int32 because it would need to be static, so is there any way to do this?
You can specify an implicit conversion directly in the structs themselves.
public struct Meter
{
public int Value;
public Meter(int value)
{
this.Value = value;
}
public static implicit operator Meter(int a)
{
return new Meter(a);
}
}
public struct Second
{
public int Value;
public Second(int value)
{
this.Value = value;
}
public static implicit operator Second(int a)
{
return new Second(a);
}
}

Anyone know how I can get FCL style initialisation syntax for c# types?

Instead of writing
int i = new int();
i = 7;
One can write
int i = 7;
Is there a way I can get that style of initialisation for my own types?
MyType mt = xyz;
The closest you can come is by creating implicit conversions on your type. For example:
public class Unit
{
public static implicit operator Unit( string val )
{
return Unit.Parse( val );
}
public static Unit Parse( string unitString )
{
// parsing magic goes here
}
}
This would enable you to do something like this:
Unit width = "150px";
var width = Unit.Parse("150px"); // equivalent to previous line
Note that you cannot introduce new syntax; this would be impossible to implement:
Unit width = 150px;
since 150px does not represent a valid value type.
Note that implicit casting can get you into trouble in weird ways so don't over do it. Support implicit casting only to and from types that you're really going to need.
Alternatively, if you're using C# compiler 3.5 or up you can also use inline initialization which is more verbose but also more explicit:
Unit with = new { Value=150, UnitType=Units.Pixel };
For the specific example in your comment you could add an implicit conversion operator to the type.
Note that doing this is generally not recommended because it makes your code less readable. For example, something like String2 s2 = new String2("yo") is completely explicit about what is happening; not so with something like String2 s2 = "yo".
String2 s2 = "yo";
// ...
public sealed class String2
{
public readonly string _value;
public string Value { get { return _value; } }
public String2(string value)
{
_value = value;
}
public override string ToString()
{
return Value;
}
public static implicit operator String2(string value)
{
return new String2(value);
}
}
You can do it through implicit cast operators.
Here's an article that describes the concept:
http://www.codeproject.com/KB/cs/Csharp_implicit_operator.aspx
short answer is "no you can't". You're always going to hide a new somewhere.
In your specific case you could do some trick with implicit conversions like this:
class String2 {
private readonly string WrappedString;
public String2(string wrappedString) {
this.WrappedString = "my modified " + wrappedString ;
}
public override string ToString() {
return this.WrappedString;
}
// the "magic" is here: the string you assign to String2 gets implicitly
// converted to a String2
public static implicit operator String2(string wrappedString) {
return new String2(wrappedString);
}
}
that enables you to do:
String2 test = "test";
Console.WriteLine(test.ToString()); // writes: "my modified test" to the Console
but you get the "new" hidden in the implicit conversion anyway.
Another approach which may be more general and lands you not too far from the syntax you want is through extension methods:
static class StringExtensions {
public static String2 ToString2(this string that) {return new String2(that);}
}
with that in scope, you can do this:
var test2="anothertest".ToString2();

Can I create accessors on structs to automatically convert to/from other datatypes?

is it possible to do something like the following:
struct test
{
this
{
get { /*do something*/ }
set { /*do something*/ }
}
}
so that if somebody tried to do this,
test tt = new test();
string asd = tt; // intercept this and then return something else
Conceptually, what you want to do here is in fact possible within .NET and C#, but you're barking up the wrong tree with regards to syntax. It seems like an implicit conversion operator would be the solution here,
Example:
struct Foo
{
public static implicit operator string(Foo value)
{
// Return string that represents the given instance.
}
public static implicit operator Foo(string value)
{
// Return instance of type Foo for given string value.
}
}
This allows you to assign and return strings (or any other type) to/from objects of your custom type (Foo here).
var foo = new Foo();
foo = "foobar";
var string = foo; // "foobar"
The two implicit conversion operators don't have to be symmetric of course, though it's usually advisable.
Note: There are also explicit conversion operators, but I think you're more after implicit operators.
You can define implicit and explicit conversion operators to and from your custom type.
public static implicit operator string(test value)
{
return "something else";
}
Expanding on MikeP's answer you want something like:
public static implicit operator Test( string value )
{
//custom conversion routine
}
or
public static explicit operator Test( string value )
{
//custom conversion routine
}

C# : How does this work : Unit myUnit = 5;

I just noticed that you can do this in C#:
Unit myUnit = 5;
instead of having to do this:
Unit myUnit = new Unit(5);
Does anyone know how I can achieve this with my own structs? I had a look at the Unit struct with reflector and noticed the TypeConverter attribute was being used, but after I created a custom TypeConverter for my struct I still couldn't get the compiler to allow this convenient syntax.
You need to provide an implicit conversion operator from int to Unit, like so:
public struct Unit
{ // the conversion operator...
public static implicit operator Unit(int value)
{
return new Unit(value);
}
// the boring stuff...
private readonly int value;
public int Value { get { return value; } }
public Unit(int value) { this.value = value; }
}
You need to provide a cast operator for the class that takes an Int32.

Categories