时间:2011-05-16 13:17:43

标签: c# generics lambda expression

我是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);
} 

2 个答案:

答案 0 :(得分:2)

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

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);

答案 1 :(得分:1)

你可以使用这样的东西

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();
        }
    }