使用表达式/lambda 设置属性值的通用方法

发布于 2025-01-05 05:08:19 字数 915 浏览 0 评论 0原文

我正在尝试找到一种通用方法来为 lambda 表达式指定的属性赋值,请查看下面的示例代码,ConverToEntities 方法的签名将如何显示以及如何调用它?

static void Main()
{
    List<long> ids = new List<long> {1, 2, 3};

    //Non generic way
    List<Data> dataItems = ids.ConvertToDataItems();

    //Generic attempt!!
    List<Data> differntDataItems =
        ids.ConvertToEntities<Data>( p => p.DataId );
}

public class Data
{
    public long DataId;
    public string Name;
}

public static class ExtensionMethods
{
    public static List<Data> ConvertToDataItems(this List<long> dataIds)
    {
        return dataIds.Select(p => new Data { DataId = p }).ToList();
    }

    public static List<T> ConvertToEntities<TProp>(
        this List<long> entities, Func<TProp> lambdaProperty )
    {
        return entities.Select(p => new T {lambdaProperty} ).ToList();
    }
}

I am trying to find a generic way to assign values to a property dictated by a lambda expression, look at the example code below, how would the signature for the ConverToEntities method look and how would it be called?

static void Main()
{
    List<long> ids = new List<long> {1, 2, 3};

    //Non generic way
    List<Data> dataItems = ids.ConvertToDataItems();

    //Generic attempt!!
    List<Data> differntDataItems =
        ids.ConvertToEntities<Data>( p => p.DataId );
}

public class Data
{
    public long DataId;
    public string Name;
}

public static class ExtensionMethods
{
    public static List<Data> ConvertToDataItems(this List<long> dataIds)
    {
        return dataIds.Select(p => new Data { DataId = p }).ToList();
    }

    public static List<T> ConvertToEntities<TProp>(
        this List<long> entities, Func<TProp> lambdaProperty )
    {
        return entities.Select(p => new T {lambdaProperty} ).ToList();
    }
}

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

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

发布评论

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

评论(3

花开雨落又逢春i 2025-01-12 05:08:19

好的。我能得到的最接近的是:

 class Program
    {
        static void Main(string[] args)
        {
            List<long> ids = new List<long> { 1, 2, 3 };

            //Non generic way
            List<Data> dataItems = ids.ConvertToDataItems();

            //Generic attempt!!

            Func<long, Data> selector = (p => new Data { DataId = p });
            List<Data> differntDataItems = ids.ConvertToEntities<Data>(selector);
        }
    }

    public class Data
    {
        public long DataId;
        public string Name;
    }

    public static class ExtensionMethods
    {
        public static List<Data> ConvertToDataItems(this List<long> dataIds)
        {
            return dataIds.Select(p => new Data { DataId = p }).ToList();
        }

        public static List<TProp> ConvertToEntities<TProp>(this List<long> entities, Func<long, TProp> selector)
        {
            return entities.Select(selector).ToList();
        }
    }

这有效。

我觉得你对你真正想要的返回类型有点困惑。如果能够在方法调用中指定我们想要的内容,那就太酷了。例如:

    public static List<TProp> ConvertToEntities<T, TProp>(List<T> entities, Func<T, TProp> selector)
    {
        return entities.Select(selector).ToList();
    }

这为我们在返回类型上提供了更大的灵活性。但由于我们使用扩展来做到这一点,我认为这是不切实际的,因为我们需要知道我们要扩展什么类型:

this List<long> entities,

好问题。

编辑代码建议修复。

Ok. The closest I could get was this :

 class Program
    {
        static void Main(string[] args)
        {
            List<long> ids = new List<long> { 1, 2, 3 };

            //Non generic way
            List<Data> dataItems = ids.ConvertToDataItems();

            //Generic attempt!!

            Func<long, Data> selector = (p => new Data { DataId = p });
            List<Data> differntDataItems = ids.ConvertToEntities<Data>(selector);
        }
    }

    public class Data
    {
        public long DataId;
        public string Name;
    }

    public static class ExtensionMethods
    {
        public static List<Data> ConvertToDataItems(this List<long> dataIds)
        {
            return dataIds.Select(p => new Data { DataId = p }).ToList();
        }

        public static List<TProp> ConvertToEntities<TProp>(this List<long> entities, Func<long, TProp> selector)
        {
            return entities.Select(selector).ToList();
        }
    }

This works.

I have the feeling you got urself a little confused with what you actually want as the return type. It would be cool to be able to specify what we want in the method call or smth. For example:

    public static List<TProp> ConvertToEntities<T, TProp>(List<T> entities, Func<T, TProp> selector)
    {
        return entities.Select(selector).ToList();
    }

This provides us more flexibility on the return type. But since we are doing this using extensions, I assume this is impractical because we need to know what type we are extending:

this List<long> entities,

Nice question.

EDIT Code suggestion fix.

温馨耳语 2025-01-12 05:08:19

你可以做这样的事情,但它并不那么简单或好。 lambda p => p.DataId 为您提供属性的 get 访问器。您可以使用Expression来获取setter,但最好直接在lambda中使用setter:

List<Data> differntDataItems =
    ids.ConvertToEntities<long, Data>((p, i) => p.DataId = i);

实现如下所示:

public static List<T> ConvertToEntities<TProp, T>(
    this List<TProp> dataIds, Action<T, TProp> lambdaProperty)
    where T : new()
{
    return dataIds.Select(
        p =>
        {
            var result = new T();
            lambdaProperty(result, p);
            return result;
        }).ToList();
}

You can do something like this, but it's not as simple or nice. The lambda p => p.DataId gives you the get accessor of the property. You could use Expressions to get the setter, but it's probably better to use the setter directly in the lambda:

List<Data> differntDataItems =
    ids.ConvertToEntities<long, Data>((p, i) => p.DataId = i);

The implementation would look like this:

public static List<T> ConvertToEntities<TProp, T>(
    this List<TProp> dataIds, Action<T, TProp> lambdaProperty)
    where T : new()
{
    return dataIds.Select(
        p =>
        {
            var result = new T();
            lambdaProperty(result, p);
            return result;
        }).ToList();
}
橘味果▽酱 2025-01-12 05:08:19

我相信@Zortkun 关于返回类型的说法是正确的。尝试以下操作:

public static List<TProp> ConvertToEntities<TProp>(
    this List<long> entities, Func<long, TProp> lambdaProperty )
{
    return entities.Select(lambdaProperty).ToList();
}

您将按如下方式调用它:

ids.ConvertToEntities<Data>( p => new Data { DataId = p } );

I believe @Zortkun is right about the return type. Try the followin:

public static List<TProp> ConvertToEntities<TProp>(
    this List<long> entities, Func<long, TProp> lambdaProperty )
{
    return entities.Select(lambdaProperty).ToList();
}

and you would call it as follows:

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