How to call constructor without new?

后端 未结 4 825
夕颜
夕颜 2021-01-20 17:50

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

4条回答
  •  清歌不尽
    2021-01-20 18:39

    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.

提交回复
热议问题