ICalityCompererの実装を抽象化するか、デフォルトの比較を使用して個別の方法を使用します

StackOverflow https://stackoverflow.com/questions/4250381

質問

私は明確なものを見つけようとしています List<Author> 与えられます List<BlogPost> それぞれ BlogPost 持っています Author 財産。私はそれを見つけました Distinct() ジェネリックの拡張方法と私はそれを使用しようとしています。まず、私のループとそれを使用したい場所を説明させてください。次に、クラスと問題がある場所を説明します。

ここでは明確な使用をしようとしています

public List<Author> GetAuthors() {

  List<BlogPost> posts = GetBlogPosts();
  var authors = new List<Author>();

  foreach (var bp in posts) {
    authors.Add(bp.Author);
  }

  return authors.Distinct().ToList();
}

私が何に基づいていますか MSDNを読んでください, Distinct() デフォルトの比較を使用するか、比較して渡されます。私は、これが1つの場所で比較を書いて、私のすべてのクラスにそれを使用できることを望んでいました(私は明らかにこれが実行可能かどうかはわかりません)。 GUID 各クラスのプロパティ)。

私のすべてのクラスはから継承します BasePage クラス:

public class BasePage : System.Web.UI.Page, IBaseTemplate, IEquatable<IBaseTemplate>, IEqualityComparer<IBaseTemplate>

public class Author : BasePage

public class BlogPost : BasePage

私のEqualsメソッドが実装されています BasePage 比較します GUID それぞれに固有のプロパティ。電話するとき Distinct()Author うまくいかないようです。比較を1か所でまとめて、常に使用することができる方法はありますか class AuhorComparer : IEqualityComparer<Auhor> それから、クラスごとに同じことを書く必要があるので、私が使用したいたびに Distinct(). または 何らかの形でデフォルトの比較をオーバーライドできますか? Distinct()?

役に立ちましたか?

解決

Distinct 操作はおそらくここでは最良の解決策ではありません。なぜなら、あなたはそれをすぐに異なる要素に縮小するためだけに、複製するだけで潜在的に非常に大きなリストを構築することになっているからです。ちょうどaから始める方がおそらく良いでしょう HashSet<Author> 大きなリストの構築を避けるため。

public List<Author> GetAuthors() { 
  HashSet<Author> authorSet = new HashSet<Author>();
  foreach (var author in GetBlogPosts().Select(x => x.Author)) {
    authorSet.Add(author);
  }
  return authorSet.ToList();
}

使用したい場合 Distinct その後、最良のルートは実装することです IEquatableAuthor タイプ。明示的なものが与えられていない場合 IEqualityComparer Distinct および他のLINQメソッドは最終的にデフォルトを使用します IEquatable タイプの実装。通常は EqualityComprare<T>.Default

他のヒント

Overriden Equalsはあなたのために働くはずです。間違っている可能性のあることの1つは、GethashCodeがEqualsとともにオーバーライドされていないことであり、フレームワークガイドラインが指示するはずです。

コードは主なアイデアのみを示していますが、これが役立つことを願っています。

public class Repository
{
    public List<Author> GetAuthors()
    {
        var authors = new List<Author>
                        {
                            new Author{Name = "Author 1"},
                            new Author{Name = "Author 2"},
                            new Author{Name = "Author 1"}
                        };
        return authors.Distinct(new CustomComparer<Author>()).ToList();
    }

    public List<BlogPost> GetBlogPosts()
    {
        var blogPosts = new List<BlogPost>
        {
            new BlogPost {Text = "Text 1"},
            new BlogPost {Text = "Text 2"},
            new BlogPost {Text = "Text 1"}
        };
        return blogPosts.Distinct(new CustomComparer<BlogPost>()).ToList();
    }
}

//This comparer is required only one.
public class CustomComparer<T> : IEqualityComparer<T> where T : class
{
    public bool Equals(T x, T y)
    {
        if (y == null && x == null)
        {
            return true;
        }
        if (y == null || x == null)
        {
            return false;
        }
        if (x is Author && y is Author)
        {
            return ((Author)(object)x).Name == ((Author)(object)y).Name;
        }
        if (x is BlogPost && y is BlogPost)
        {
            return ((BlogPost)(object)x).Text == ((BlogPost)(object)y).Text;
        }
        //for next class add comparing logic here
        return false;
    }

    public int GetHashCode(T obj)
    {
        return 0; // actual generating hash code should be here
    }
}

public class Author
{
    public string Name { get; set; }
}

public class BlogPost
{
    public string Text { get; set; }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top