1

それぞれがプロパティを持っている場所をList<Author>指定して、個別のものを見つけようとしています。ジェネリックで拡張メソッドを見つけたので、それを使用しようとしています。最初に、ループとそれを使用する場所について説明し、次にクラスと問題のある場所について説明します。List<BlogPost>BlogPostAuthorDistinct()

ここで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それはうまくいかないようです。class AuhorComparer : IEqualityComparer<Auhor>使用するたびにクラスごとに同じことを書く必要があるため、比較子を1か所にまとめて、常に使用できるようにする方法はありますかDistinct()? または、デフォルトの比較子を何らかの方法でオーバーライドして、何も渡す必要がないようにすることはできますDistinct()か?

4

3 に答える 3

2

このDistinct操作はおそらく最良の解決策ではありません。これは、重複する可能性のある非常に大きなリストを作成してから、すぐにそれを個別の要素に縮小することになるためです。HashSet<Author>大きなリストを構築することを避けるために、 a から始める方がおそらく良いでしょう。

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に実装するのが最善の方法です。明示的に指定されていない場合、 theおよびその他の LINQ メソッドは、最終的にデフォルトでその型の実装を使用します。通常通りIEquatableAuthorIEqualityComparerDistinctIEquatableEqualityComprare<T>.Default

于 2010-11-22T21:35:46.473 に答える
0

Overriden Equals はあなたのために働くはずです。間違っている可能性があることの 1 つは、GetHashCode が Equals と一緒にオーバーライドされていないことです。

于 2010-11-22T21:34:54.303 に答える
0

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

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; }
}
于 2010-11-22T22:16:55.127 に答える