3

を使用してオブジェクトをXMLにシリアル化System.Xml.Serializationしていますが、これにはパラメーターなしのコンストラクターが必要です。

したがって、オブジェクト初期化構文を使用して特定のプロパティに値を割り当て、オブジェクトをXMLにシリアル化する前に、コンストラクターロジックを使用してこれらの値を必要に応じてフォーマットしようとしています。

私の問題は、プロパティに値が割り当てられる前にコンストラクターが実行されることです。簡単な例を以下に示します。

class Program
{
    static void Main(string[] args)
    {
        Foo myFoo = new Foo() { HelloWorld = "Beer", HelloWorldAgain = "More beer" };

        Console.WriteLine(myFoo.HelloWorld);
        Console.WriteLine(myFoo.HelloWorldAgain);

        Console.ReadLine();
    }
}

public class Foo : Bar
{
    public string HelloWorld { get; set; }

    public Foo()
    {
        Console.WriteLine("Foo Was Initialized");
        Console.WriteLine(HelloWorld);
    }
}

public abstract class Bar
{
    public string HelloWorldAgain { get; set; }

    public Bar()
    {
        Console.WriteLine("Bar was initialized");
        Console.WriteLine(HelloWorldAgain);
    }
}

これにより、次の出力が得られます。

出力

ご覧のとおり、コンストラクタロジックが実行され、プロパティに値が割り当てられます。逆に機能するには、これが必要です。

これは可能ですか?

4

4 に答える 4

6

シリアル化では、パラメーターなしのコンストラクターが必要ですが、その 1 つのコンストラクターに限定されるわけではありません。

逆シリアル化のために引数なしのコンストラクターを保持しますが、コードでクラスをインスタンス化する必要がある場合は、値を受け取り、必要な初期化を行う別のコンストラクターを追加します。

オブジェクトの初期化構文は、構築後にプロパティを設定するための省略形です。

于 2012-06-20T18:13:30.823 に答える
5

いいえ。オブジェクトの初期化構文は単なるショートカットです。あなたが書くとき:

Foo foo = new Foo { HelloWorld  = "Beer" };

コンパイラは、これを、次のように記述した場合に非常に近いものに書き換えるだけです。

Foo foo = new Foo();
foo.HelloWorld  = "Beer";

オブジェクトが存在するためにパラメーターが必要な場合は、それらをコンストラクターに引数として配置する必要があります。

于 2012-06-20T18:11:27.057 に答える
2

いいえ、オブジェクトのプロパティを初期化できるようにするために、オブジェクトが既に存在しているため、不可能です。その存在は、他のすべてのものの前にctor を実行することによって保証されます。

概念的な質問のように、「デフォルトのコンストラクターを実行していない」ことについて話している場合。プロパティを使用してそれを行うことができstaticます。その場合、Foo() は呼び出されません。しかし、それは当然今の質問の主題から外れています。

于 2012-06-20T18:09:54.227 に答える
1

間違いなく、構文は欺瞞的です。ここで何が起きてるの?

var myFoo = new Foo();
myFoo.HelloWorld = "Beer";
myFoo.HelloWorldAgain = "MoreBeer";

それだけです、私は恐れています。コンストラクターが実行される前にプロパティを初期化することは単純に不可能です。コンストラクターは、オブジェクトのメモリーが割り当てられ、デフォルト値がフィールドに割り当てられた後、最初に「発生」します。

ところで、オブジェクト初期化構文を使用する親は必要ありません。これは同じくらい良いでしょう(しかしさらに欺瞞的です):

var myFoo = new Foo { HelloWorld = "Beer", HelloWorldAgain = "MoreBeer" };

あなたの質問を見ると、あなたがやろうとしていること(シリアル化の前にプロパティを変更すること)はコンストラクターに属していないようです。

于 2012-06-20T18:14:11.220 に答える