Using string constants in implicit conversion - c#

Consider the following code:
public class TextType {
public TextType(String text) {
underlyingString = text;
}
public static implicit operator String(TextType text) {
return text.underlyingString;
}
private String underlyingString;
}
TextType text = new TextType("Something");
String str = text; // This is OK.
But I want to be able do the following, if possible.
TextType textFromStringConstant = "SomeOtherText";
I can't extend the String class with the TextType implicit operator overload, but is there any way to assign a literal string to another class (which is handled by a method or something)?
String is a reference type so when they developed C# they obviously had to use some way to get a string literal to the class. I just hope it's not hardcoded into the language.

public static implicit operator TextType(String text) {
return new TextType(text);
}

Add
public static implicit operator TextType(string content) {
return new TextType(content);
}
to your class? :)

Related

C# custom variables

I was experimenting with making a custom variables but got stuck.
I'm still new to C# so it's only expected for me to not know what's happening, I guess..
struct MyCustomStringVariable
{
public static implicit operator MyCustomStringVariable(string input)
{
return input;
}
}
class Program
{
static MyCustomStringVariable myCustomString = "This is a string!";
static void Main(string[] args)
{
Console.WriteLine(myCustomString);
Console.ReadLine();
}
}
The following exception is thrown
System.StackOverflowException: 'Exception of type 'System.StackOverflowException' was thrown.'
This is because the code is stuck in an infinit loop. Your implicit operator will call itself because it returns the original input string which does not throw an exception because of the defined operator.
public static implicit operator MyCustomStringVariable(string input)
{
return input; // returning string type will call this method again
}
should be
public static implicit operator MyCustomStringVariable(string input)
{
// and use input somewhere on the returned type
return new MyCustomStringVariable();
}
That said there is probably no reason for you to define a type named MyCustomStringVariable but that is hard to tell because you never share the code for this or how you intend to use it.
My final goal is to visualize the process of making a string variable in my head so that I can better understand the concept behind it.
I am not sure how your custom struct or its implicit operator fit in with this goal. Why not just use the type string?
static string myCustomString = "This is a string!";
It's because the implicit operator is called recursively. You'll need to implement your structure as so, encapsulating your string variable somehow.
struct MyCustomStringVariable
{
private string value;
public MyCustomStringVariable(string input)
{
value = input;
}
public static implicit operator MyCustomStringVariable(string input)
{
return new MyCustomStringVariable(input);
}
public string GetValue()
{
return value;
}
}
Then, calling it like
Console.WriteLine(myCustomString.GetValue());
You can refer to the documentation here.

Operator Overloading- concatenating two strings

In the following code, I am getting the error that One of the parameters of a binary operator must be the containing type
Whats wrong with the code?
public class Nest
{
public string a = "Test";
public string b = "Code";
}
class OperatorOverload
{
public static void Main(string[] args)
{
Nest n = new Nest();
Console.WriteLine("Enter first string");
n.a = Console.ReadLine();
Console.WriteLine("Enter second string");
n.b = Console.ReadLine();
Console.WriteLine(n.a + n.b);
}
public static string operator + (string a, string b)
{
a = string.Concat(b);
a = string.Concat(a);
return a;
}
}
Well if if was me I'd override ToString() on Nest, to return String.Concat(a,b).
Saves a lot of bogging about , when you add a c property to it.
From MSDN
Use the operator keyword to overload a built-in operator or to provide a user-defined conversion in a class or struct declaration.
what are you doing it's wrong you should define it in class like in msdn example documentation

Create a class which can be instantiated like the XNamespace class

A XNamespace object can be created as below:
XNamespace ns="http://www.xyz.com";
Here the string "http://www.xyz.com" is interpreted as a property value(NamespaceName) of that class. I was wondering if I can create such a custom class where it can just be instantiated like that. The syntax actually looks pretty cool.
class MyClass
{
public string Value {get; private set;}
public MyClass(string s)
{
this.Value = s;
}
public static implicit operator MyClass(string s)
{
return new MyClass(s);
}
}
now you can:
MyClass myClass = "my string";
Console.WriteLine(myClass.Value); //prints "my string"
Note, that XNamespace also support addition operator, that accepts strings as right parameter. This is quite a good API decision, if you are dealing with strings. To implement this, you can overload addition operator as well:
//XNamespace returns XName (an instance of another type)
//but you can change it as you would like
public static MyClass operator +(MyClass val, string name)
{
return new MyClass(val.Value + name);
}
You just need to add an implicit conversion operator from string:
public class Foo
{
private readonly string value;
public Foo(string value)
{
this.value = value;
}
public static implicit operator Foo(string value)
{
return new Foo(value);
}
}
I'd use this with caution though - it makes it less immediately obvious what's going on when reading the code.
(LINQ to XML does all kinds of things which are "a bit dubious" in terms of API design... but manages to get away with it because it all fits together so neatly.)

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();

Is it possible to cast string into my own type?

public class Currency{
private Code {get;set;}
public Currency(string code){
this.Code = code;
}
//more methods here
}
I want to be able to make my object castable
string curr = "USD";
Currency myType = (Currency)curr;
I know that I can do it with the contructor, but I have usecase where I need to cast without initializing the object...
I also believe that ill need a function like FromString() to do it
Thanks.
Yes, just add an explicit cast operator:
public class Currency {
private readonly string code;
public string Code { get { return this.code; } }
public Currency(string code) {
this.code = code;
}
//more methods here
public static explicit operator Currency(string code) {
return new Currency(code);
}
}
Now you can say:
string curr = "USD";
Currency myType = (Currency)curr;
Add this method to your Currency class:
public static explicit operator Currency(String input)
{
return new Currency(input);
}
And call it like this:
Currency cur = (Currency)"USD";
If you create your own cast-operators for your type, you can make this possible.
check out the implicit and explicit keywords.
(in this case, I'd prefer an explicit cast).
I believe this operator does what you want (as part of your Currency class):
public static explicit operator Currency(stringvalue){
return new Currency(value);
}

Categories