合并通用方法

发布于 2024-11-07 12:21:06 字数 1233 浏览 0 评论 0原文

我是 C# 新手,我有以下 3 种方法。这些方法允许调用者通过在给定方法上指定 lambda 表达式来检索表的不同属性。然而,我有一种感觉,专家会将它们进一步组合成一个通用方法。如果可能的话,请告诉我如何做。

private KeyValuePair<T, int> GetHeaderProperty<T>(Func<Header, T> Property, 
                                                  Source ds)
{
    Func<Source, Header> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId)
                 .First().Header;
    return new KeyValuePair<T,int>(Property(GetValue(ds)), 0);
} 

private KeyValuePair<T, int> GetBookProperty<T>(Func<Book, T> Property,
                                               Source ds)
{
    Func<Source, Book> GetValue = 
        a => Books.Where(str => str.BookId == a.DiscardBookId).First();

    return new KeyValuePair<T, int>(Property(GetValue(ds)), 0);
} 

private KeyValuePair<T, int> GetFleetProperty<T>(Func<Fleet, T> Property,
                                                 Source ds)
{
    Func<Source,Fleet> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId).First()
                 .Header.Fleet;

    return new KeyValuePair<T,int>(Property(GetValue(ds)), 0);
} 

I'm new to C# and I have the following 3 methods. These methods allow the caller to retrieve differents properties of the table by specifying a lambda expression on the given method. However, I have the feeling an expert would combine them even further into a single generic method. If this is possible, please let me know how.

private KeyValuePair<T, int> GetHeaderProperty<T>(Func<Header, T> Property, 
                                                  Source ds)
{
    Func<Source, Header> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId)
                 .First().Header;
    return new KeyValuePair<T,int>(Property(GetValue(ds)), 0);
} 

private KeyValuePair<T, int> GetBookProperty<T>(Func<Book, T> Property,
                                               Source ds)
{
    Func<Source, Book> GetValue = 
        a => Books.Where(str => str.BookId == a.DiscardBookId).First();

    return new KeyValuePair<T, int>(Property(GetValue(ds)), 0);
} 

private KeyValuePair<T, int> GetFleetProperty<T>(Func<Fleet, T> Property,
                                                 Source ds)
{
    Func<Source,Fleet> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId).First()
                 .Header.Fleet;

    return new KeyValuePair<T,int>(Property(GetValue(ds)), 0);
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷梦 2024-11-14 12:21:06

我认为以下内容相当于连续调用所有三个方法并将结果添加到列表中:

private IEnumerable<KeyValuePair<T, int>> GetFleetProperty<T>(
                                              Func<Book, T> PropertyBook,
                                              Func<Header, T> PropertyHeader,
                                              Func<Fleet, T> PropertyFleet,
                                              Source ds)
{
    Func<Source,Fleet> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId).First();

    var book = GetValue(ds);
    var result = new List<KeyValuePair<T, int>>();
    result.Add(new KeyValuePair<T, int>(PropertyBook(book), 0);
    result.Add(new KeyValuePair<T, int>(PropertyHeader(book.Header), 0);
    result.Add(new KeyValuePair<T, int>(PropertyFleet(book.Header.Fleet), 0);
    return result;
} 

更新:
您还可以创建这样的方法:

private KeyValuePair<T, int> GetProperty<T, TProperty>(
                                 Func<TProperty, T> Property, 
                                 Func<Book, TProperty> GetProperty, 
                                 Source ds)
{
    Func<Source, Header> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId)
                 .First();
    var book = GetValue(ds);
    return new KeyValuePair<T,int>(Property(GetProperty(book)), 0);
} 

对于 Header,您可以这样称呼它:

GetProperty(xyz, b => b.Header, ds);

对于 Book,您可以这样称呼它:

GetProperty(xyz, b => b, ds);

对于 Fleet,您可以这样称呼它:

GetProperty(xyz, b => b.Header.Fleet, ds);

I think the following will be equivalent to calling all three methods in a row and adding the results to a list:

private IEnumerable<KeyValuePair<T, int>> GetFleetProperty<T>(
                                              Func<Book, T> PropertyBook,
                                              Func<Header, T> PropertyHeader,
                                              Func<Fleet, T> PropertyFleet,
                                              Source ds)
{
    Func<Source,Fleet> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId).First();

    var book = GetValue(ds);
    var result = new List<KeyValuePair<T, int>>();
    result.Add(new KeyValuePair<T, int>(PropertyBook(book), 0);
    result.Add(new KeyValuePair<T, int>(PropertyHeader(book.Header), 0);
    result.Add(new KeyValuePair<T, int>(PropertyFleet(book.Header.Fleet), 0);
    return result;
} 

UPDATE:
You could also create a method like this:

private KeyValuePair<T, int> GetProperty<T, TProperty>(
                                 Func<TProperty, T> Property, 
                                 Func<Book, TProperty> GetProperty, 
                                 Source ds)
{
    Func<Source, Header> GetValue =
        a => Books.Where(str => str.BookId == a.DiscardBookId)
                 .First();
    var book = GetValue(ds);
    return new KeyValuePair<T,int>(Property(GetProperty(book)), 0);
} 

You would call it like this for Header:

GetProperty(xyz, b => b.Header, ds);

You would call it like this for Book:

GetProperty(xyz, b => b, ds);

You would call it like this for Fleet:

GetProperty(xyz, b => b.Header.Fleet, ds);
喜你已久 2024-11-14 12:21:06

你可以使用这样的东西

public interface IPieceProvider<T>
    {
        T GetPiece();
    }

    public class Fleet
    {
        public string Test;
    }

    public class Header
    {
        public Fleet Fleet;
        public string Test;
    }

    public class Source
    {
        public int DiscardBookId;
    }

    public partial class Book
        : IPieceProvider<Book>, IPieceProvider<Header>, IPieceProvider<Fleet>
    {
        public int BookId;
        public Header Header;
        public string Test;

        Book IPieceProvider<Book>.GetPiece()
        {
            return this;
        }

        Header IPieceProvider<Header>.GetPiece()
        {
            return Header;
        }

        Fleet IPieceProvider<Fleet>.GetPiece()
        {
            return Header.Fleet;
        }
    }

    class Program
    {
        Book[] Books;

        private KeyValuePair<T, int> GetProperty<T, TP>(Func<TP, T> propertyGetter, Source ds)
        {
            return Books
                .Where(b => b.BookId == ds.DiscardBookId)
                .Cast<IPieceProvider<TP>>()
                .Select(p => p.GetPiece())
                .Select(p => new KeyValuePair<T, int>(propertyGetter(p), 0))
                .First();
        }

        static void Main(string[] args)
        {
            var source = new Source();
            var prg = new Program();
            var bookTest = prg.GetProperty((Book b) => b.Test, source);
            var headerTest = prg.GetProperty((Header h) => h.Test, source);
            var fleetTest = prg.GetProperty((Fleet f) => f.Test, source);

            Console.ReadKey();
        }
    }

You can use some thing like this

public interface IPieceProvider<T>
    {
        T GetPiece();
    }

    public class Fleet
    {
        public string Test;
    }

    public class Header
    {
        public Fleet Fleet;
        public string Test;
    }

    public class Source
    {
        public int DiscardBookId;
    }

    public partial class Book
        : IPieceProvider<Book>, IPieceProvider<Header>, IPieceProvider<Fleet>
    {
        public int BookId;
        public Header Header;
        public string Test;

        Book IPieceProvider<Book>.GetPiece()
        {
            return this;
        }

        Header IPieceProvider<Header>.GetPiece()
        {
            return Header;
        }

        Fleet IPieceProvider<Fleet>.GetPiece()
        {
            return Header.Fleet;
        }
    }

    class Program
    {
        Book[] Books;

        private KeyValuePair<T, int> GetProperty<T, TP>(Func<TP, T> propertyGetter, Source ds)
        {
            return Books
                .Where(b => b.BookId == ds.DiscardBookId)
                .Cast<IPieceProvider<TP>>()
                .Select(p => p.GetPiece())
                .Select(p => new KeyValuePair<T, int>(propertyGetter(p), 0))
                .First();
        }

        static void Main(string[] args)
        {
            var source = new Source();
            var prg = new Program();
            var bookTest = prg.GetProperty((Book b) => b.Test, source);
            var headerTest = prg.GetProperty((Header h) => h.Test, source);
            var fleetTest = prg.GetProperty((Fleet f) => f.Test, source);

            Console.ReadKey();
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文