i know that string is like a class, and when creating a new string the string itself doesnt owe the value but only the value\'s pointer. but when creating a string there is
You can use cast operator to implicitly:
sealed class Student
{
public string Name
{
get;
private set;
}
Student()
{
}
public static implicit operator Student(string name)
{
return new Student
{
Name = name
};
}
}
Then you can do Student student = "Sabrina";
.
The string "hello"
in your code, in all cases, does not involve a call to a constructor. It is a constant value, created at compile time, such that all instances of the string "hello"
are all the same object. Similarly, the integer 1
and decimal value 3.456
, and any other "literal" value, are constants that exist before runtime, before the constructor code can have a chance to be called.
The code new string("hello");
cannot be called, as there is no constructor for string that takes a string as a value. However, if you changed it to new string("hello".ToCharArray());
, you would get a string object, but it won't be the same thing as the string "hello"
. You've actually created a new string, at a separate memory location, from just plain "hello"
. It only just so happens to have the same character values contained in it as "hello"
.
The significance is that, if you do use the implicit type conversion trick, then one string literal converted to your type will not be the same object:
class Foo
{
private string value;
public Foo(string val)
{
this.value = val;
}
public static implicit operator Foo(string value)
{
return new Foo(value);
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Foo a = "asdf";
Foo b = "asdf";
Assert.AreNotEqual(a, b);
}
}
In other words, a.Equals(b)
returns false. In order to make the Equals method return true, you'll have to override the Equals method in your Foo class.
public override bool Equals(object obj)
{
return obj is Foo && value.Equals(((Foo)obj).value);
}
But, as mentioned by other posters, this is an obfuscation. You'll make it difficult to use the code as well as difficult to debug it. It changes what looks like a regular assignment to a full method call. And it breaks many of the tools that Visual Studio provides for inspecting code, such as F12 to jump to a method definition.
Implicit type conversion should be used only in cases where the two types are actually quite interchangeable in use, with minor differences in their functionality. The float
type can implicitly convert to double
because there are no extra methods and functions for double
vs float
, and increasing the precision from float
to double
does not change the value. However, going from double
to float
requires an explicit cast, because the loss of precision changes the value represented.
You could have a method named createObject() and use that while having the constructors private, discourage their use.
Although you can get this done using an implicit operator
, I would highly recommend not doing this at all. Strings
are special animals in C# and they get special treatment - along with other special classes like int
and float
, you can create them without explicitly new
ing them up due to the way the C# compiler works:
var myInt = 0;
var myFloat = 0f;
var myString = "string";
However, this behavior is typically restricted to those special classes. Adding an implicit operator
to do this is bad practice for multiple reasons:
new Student
under the hood when converting from a string
? Student
's ID number as well?var student = "name"
; you must call Student student = "name"
.The implicit operator
paradigm breaks down very quickly. Though it's a cool thing to do, you're setting yourself up for a bad time down the road and making your code more difficult to read. I would highly advise just using new Student("name")
like all other normal objects in C#.