Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 412
Victor Mukherjee Avatar asked Feb 17 '23 04:02

Victor Mukherjee


2 Answers

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);
}
like image 53
Ilya Ivanov Avatar answered May 03 '23 13:05

Ilya Ivanov


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.)

like image 26
Jon Skeet Avatar answered May 03 '23 12:05

Jon Skeet