8

データを含めるためだけに機能するクラスがいくつかあります。例えば

public class EntityAdresse : IEntityADRESSE
{
    public string Name1 { get; set; }
    public string Strasse { get; set; }
    public string Plz { get; set; }
    public string Ort { get; set; }
    public string NatelD { get; set; }
    public string Mail { get; set; }
    public int Id_anrede { get; set; }
    public string Telefon { get; set; }
    public int Id_adr { get; set; }
    public int Cis_adr { get; set; }
}

これはアドレスを表します。私が言ったように、それはデータだけを含んでいます。メソッドなし(ここではインターフェイスが意味をなさないことはわかっています...)

次に、このすべてのエンティティクラスにToStringを実装する必要があり、それらはたくさんあります。

私の質問は:このtostringメソッドを自動的に生成するC#のメタプログラミング機能はありますか?これらのクラスのすべてにボイラープレートコードを書きたくありません。

あるいは、perlまたはpythonスクリプトを記述してコードを生成することもできます。しかし、私はC#で直接それを行うことを好みます。

4

5 に答える 5

11

通常、クラスのすべてのプロパティ値を取得し、それらを1つの文字列に結合する必要があります。これは、次のアプローチを使用して実行できます。

public override string ToString() 
{
    PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(this);
    StringBuilder builder = new StringBuilder();
    foreach(PropertyDescriptor pd in coll)
    {
        builder.Append(string.Format("{0} : {1}", pd.Name , pd.GetValue(this).ToString()));
    }
    return builder.ToString();
}
于 2013-03-06T10:14:11.910 に答える
3

この機能は反射と呼ばれます。最も簡単な例は次のとおりです。

  public class EntityBase
  {
      public override string ToString()
      {
          StringBuilder sb = new StringBuilder();

          foreach ( var property in this.GetType().GetProperties() )
          {
              sb.Append( property.GetValue( this, null ) );
          }

          return sb.ToString();
      } 
  }

  public class TheEntity : EntityBase
  {
      public string Foo { get; set; }
      public string Bar { get; set; }
  }

要件を満たすように微調整してください。

ご覧のとおり、基本クラスに単一の実装を設定して、すべての子孫が自動的に同じ動作を継承するようにするという考え方です。

于 2013-03-06T10:17:14.197 に答える
2

これを自動的に行う機能は言語に組み込まれていませんがExpression、フレームワークの機能を使用してそれを行うライブラリを作成し、それを行う関数を生成することができます。

次のような関数があります。

Func<T,string> GenerateToString<T>()

そしてあなたのクラスにはこのようなものがあります:

public class EntityAdresse : IEntityADRESSE
{
    private static readonly Func<EntityAdresse,string> s_ToString=Generator.GenerateToString<EntityAdresse>();

    public string Name1 { get; set; }
    public string Strasse { get; set; }
    public string Plz { get; set; }
    public string Ort { get; set; }
    public string NatelD { get; set; }
    public string Mail { get; set; }
    public int Id_anrede { get; set; }
    public string Telefon { get; set; }
    public int Id_adr { get; set; }
    public int Cis_adr { get; set; }

    public override ToString()
    {
       return s_ToString(this);
    }
}

課題は書くことGenerateToStringです。フレームワークとリフレクションを使用するExpressionと、コードを手動で記述した場合と同じくらい効率的なデリゲートを作成できます。

リフレクションを単独で使用することもできますが、パフォーマンスへの影響がすぐに問題になり始めます。

于 2013-03-06T10:19:07.343 に答える
2

ToStringを自動生成するためのオープンソースフレームワークStatePrinterがあります。それは非常に構成可能であるため、ニーズに応える必要があります。イントロスペクションコードはイントロスペクションにあります

于 2014-04-06T11:57:48.560 に答える
2

すでに言われていることの短いバージョン:

public override string ToString()
{
    var propertyStrings = from prop in GetType().GetProperties()
                          select $"{prop.Name}={prop.GetValue(this)}";
    return string.Join(", ", propertyStrings);
}
于 2018-11-16T23:49:48.397 に答える