1

[下手なタイトルでごめんなさい - 私がやろうとしていることを表現する最善の方法がわかりませんでした。]

少しばかげているように感じます-次のコードでバグを発見しました:

private static XmlSchemaSet internalSchema = null;
private static XmlSchemaSet externalSchema = null;
private static XmlSchemaSet GetSchema(SchemaType schemaType)
{
    // Lazy evaluation of schema objects - only create internal
    // and external schema once
    XmlSchemaSet schema =
        schemaType == SchemaType.Internal ? internalSchema : externalSchema;
    if (schema == null)
    {
        schema = new XmlSchemaSet();
        schema.Add("", CreateXmlSchemaFile(schemaType));
    }
    return schema;
}

コードの目的は、静的メンバーinternalSchemaexternalSchema最初に要求されたときに 1 回だけ割り当てることです。

もちろん、私が試みた簡潔なコードには明らかなバグがあります。schemaローカル参照は、またはが指している (最初は)オブジェクトを指していますが、 を呼び出すとすぐに、静的メンバーではなく、ローカル参照のみが再割り当てされます。internalSchemaexternalSchemanullnew

私がやろうとしていることを達成する簡単な方法はありますか? XmlSchemaSetviaキーワードを取る別のメソッドを作成できると思いますがref、このためだけに別のメソッドを作成するのはばかげているようです。

4

2 に答える 2

4

怠惰なクラスはあなたが探しているものです。

おおよその使用法:

private static Lazy<XmlSchemaSet> internalSchema = new Lazy<XmlSchemaSet>(
  () => {
   schema = new XmlSchemaSet();
   schema.Add("", CreateXmlSchemaFile(SchemaType.Internal));
   return schema;
  });
于 2012-05-23T02:01:07.727 に答える
2

いいえ、「参照型への参照」をローカル変数に割り当てる簡単な方法はありません。メソッドにパラメーターを使用するrefことが、それを実現する唯一の直接的な方法です。

.NET 4.0 を使用している場合は、Lazy<>クラスを使用して必要な方法で遅延初期化を行うことができます。これにより、(IMO) 一般的なケースのアクセス コードから 1 回限りの初期化コードを削除することで、コードを読みやすくすることができます。 :

private static Lazy<XmlSchemaSet> internalSchema = new Lazy<XmlSchemaSet>(() => CreateSchema(SchemaType.Internal));
private static Lazy<XmlSchemaSet> externalSchema = new Lazy<XmlSchemaSet>(() => CreateSchema(SchemaType.External));

private static XmlSchemaSet CreateSchema(SchemaType schemaType)
{
    var schema = new XmlSchemaSet();
    schema.Add("", CreateXmlSchemaFile(schemaType));
    return schema;
}

private static XmlSchemaSet GetSchema(SchemaType schemaType)
{
    return schemaType == SchemaType.Internal 
      ? internalSchema.Value 
      : externalSchema.Value;
}

それ以外の場合は、派手になりすぎず、自分のやりたいことを正確に実行できるようにコードを記述することをお勧めします。「正しい」コードは、100% の確率で「簡潔な」コードよりも優れています。

if (schemaType == SchemaType.Internal)
{ 
    if (internalSchema == null)
    {
        internalSchema = new XmlSchemaSet();
        internalSchema.Add("", CreateXmlSchemaFile(schemaType));
    }
    return internalSchema;
}
else
{
    if (externalSchema == null)
    {
        externalSchema = new XmlSchemaSet();
        externalSchema.Add("", CreateXmlSchemaFile(schemaType));
    }
    return externalSchema;
}
于 2012-05-23T02:06:09.347 に答える