3

ActiveRecord T4 テンプレートで SubSonic 3 を使用している間、生成されたコードは、CLS 準拠、未使用の項目、および GetHashCode() 実装の欠如に関する多くの警告を示します。

それらを回避するために、次の変更を行いました。

// Structs.tt
[CLSCompliant(false)]                                    // added
public class <#=tbl.CleanName#>Table: DatabaseTable
{ ...

// ActiveRecord.tt
[CLSCompliant(false)]                                    // added
public partial class <#=tbl.ClassName#>: IActiveRecord
{
    #region Built-in testing
    #pragma warning disable 0169                         // added
    static IList<<#=tbl.ClassName#>> TestItems;
    #pragma warning restore 0169                         // added
    ...

    public override Int32 GetHashCode()                  // added
    {
      return this.KeyValue().GetHashCode();
    }

    ...

警告を取り除くためのより良い方法はありますか? または、より良い GetHashCode() 実装ですか?

4

2 に答える 2

2

現在、警告を取り除く唯一の方法は、t4テンプレートを更新し、バグ/修正をRobに送信することです。または、他の誰かがそうするまで待ちます。

GetHashCodeの実装に関しては、テンプレートを使用してこれを行うための良い方法を見つけることはできないと思います。ハッシュコードの生成は、オブジェクトに含まれる状態に大きく依存します。また、名前の後に文字がたくさんある人は、高速で衝突の可能性が低い結果を返すハッシュコードアルゴリズムを思い付くのに長く苦労します。保持する可能性のある状態の数百万の異なる順列を持つクラスを生成する可能性のあるテンプレート内からこれを行うことは、満たすのが難しい注文です。

おそらく、Robが実行できた最善のことは、部分メソッドを呼び出し、結果をチェックし、見つかった場合はそれを返すデフォルトの実装を提供することです。次に例を示します。

public partial class Foo
{
    public override int GetHashCode()
    {
        int? result = null;
        TryGetHashCode(ref result);
        if (result.HasValue)
            return result.Value;
        return new Random().Next();
    }

    partial void TryGetHashCode(ref int? result);
}

public partial class Foo
{
    partial void TryGetHashCode(ref int? result)
    {
        result = 5;
    }
}

TryGetHashCodeを実装せずにこれをコンパイルすると、コンパイラはTryGetHashCodeの呼び出しを完全に省略し、結果の宣言から、値があるかどうかのチェックに進みます。値があるかどうかを確認するため、ハッシュコードのデフォルトの実装は次のようになります。戻ってきた。

于 2009-07-12T19:13:09.183 に答える
1

これも早急に解決したいと思いました。私が使用しているバージョンは、単一の int である主キーを持つテーブルの GetHashCode を生成します。

私たちの単純なテーブルはテキストを主キーとして使用しているため、そのままでは機能しませんでした。そこで、ActiveRecord.tt の 273 行目付近のテンプレートに次の変更を加えました。

<#      if(tbl.PK.SysType=="int"){#>

        public override int GetHashCode() {
            return this.<#=tbl.PK.CleanName #>;
        }
<#      }#>
<#      else{#>
        public override int GetHashCode() {
            throw new NotImplementedException();
        }
<#      }#>

このようにして、すべてのテーブルに対して GetHashCode が生成され、警告が停止しますが、呼び出された場合は例外がスローされます (これはありません)。

これは、Web サイトなどではなく、アプリケーションのテスト用に使用します。このアプローチは、多くの状況では有効ではない可能性があります。

于 2009-08-10T00:19:07.243 に答える