4

私は文字列がクラスのようなものであることを知っています.新しい文字列を作成するとき、文字列自体は値を負っていませんが、値のポインタのみを負っています. ただし、文字列を作成するときは、new という単語を使用する必要はありません。

string a = "hello";

そしてそうではない

string a = new string("hello");

2番目のオプションも可能であることは知っていますが、理解したいのはなぜ最初のオプションなのですか?

彼のコンストラクターが取得するクラス名の学生がいるとしましょうstring。新しいクラスを作成するには、保存された単語 new を使用する必要があります。

student example = new student("Sabrina");

オーバーロードを試みoparator =ましたが、不可能です。

stringのように(単語を使用せずに)新しいクラスを作成するにはどうすればよいnewですか?

student example = "Sabrina"; 
4

4 に答える 4

6

コード内の文字列"hello"は、すべての場合において、コンストラクターの呼び出しを伴いません。"hello"文字列のすべてのインスタンスがすべて同じオブジェクトになるように、コンパイル時に作成される定数値です。同様に、integer1と decimal 値3.456、およびその他の「リテラル」値は、ランタイム前、つまりコンストラクター コードが呼び出される前に存在する定数です。

new string("hello");文字列を値として受け取る文字列のコンストラクターがないため、コードを呼び出すことはできません。ただし、に変更するとnew string("hello".ToCharArray());、文字列オブジェクトが得られますが、文字列と同じではありません"hello"。実際には、単純な から別のメモリ位置に新しい文字列を作成しました"hello"。と同じ文字値が含まれているのはたまたま"hello"です。

重要なのは、暗黙的な型変換トリックを使用すると、型に変換された 1 つの文字列リテラルが同じオブジェクトにならないということです。

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

つまり、a.Equals(b)false を返します。Equals メソッドが true を返すようにするには、Foo クラスで Equals メソッドをオーバーライドする必要があります。

public override bool Equals(object obj)
{
    return obj is Foo && value.Equals(((Foo)obj).value);
}

しかし、他のポスターで述べたように、これは難読化です。コードの使用とデバッグが困難になります。通常の割り当てのように見えるものを完全なメソッド呼び出しに変更します。また、F12 キーを押してメソッド定義にジャンプするなど、コードを検査するために Visual Studio が提供するツールの多くが機能しなくなります。

暗黙的な型変換は、2 つの型が実際に互換性があり、機能にわずかな違いがある場合にのみ使用する必要があります。vsには追加のメソッドや関数がなく、精度を からに上げても値は変わらないため、float型は暗黙的に に変換できます。ただし、精度が失われると表現される値が変わるため、からへの変換には明示的なキャストが必要です。doubledoublefloatfloatdoubledoublefloat

于 2013-09-02T17:34:08.117 に答える
6

を使用してこれを実行できimplicit operatorますが、これをまったく実行しないことを強くお勧めします。Stringsは C# の特別な動物であり、特別な扱いを受けます - や のような他の特別なクラスと同様intに、C# コンパイラの動作方法により、float明示的に指定しなくても作成できます。new

var myInt = 0;
var myFloat = 0f;
var myString = "string";

ただし、この動作は通常、これらの特別なクラスに制限されています。これを行うために を追加するimplicit operatorことは、複数の理由から悪い習慣です。

  • 実際に何が起こっているかを隠します。new Studentから変換するときに、内部でを作成していstringますか?
  • それは維持不可能です。Studentの ID 番号も含めるために、コンストラクターに別のパラメーターを追加する必要がある場合はどうなりますか?
  • 暗黙的に型指定された変数を使用する可能性を排除します。呼び出すことはできませんvar student = "name"。電話する必要Student student = "name"があります。

パラダイムはimplicit operatorすぐに崩壊します。これは素晴らしいことですが、将来的には最悪の事態に備え、コードを読みにくくすることになります。new Student("name")C# の他のすべての通常のオブジェクトと同じように使用することを強くお勧めします。

于 2013-09-02T17:35:01.337 に答える