将值从一个对象复制到另一个对象(不同类型)

2023-11-30

我需要将一个对象的某些属性复制到另一个对象。但是,某些属性需要从十进制到整数的类型转换。

我发现这个问题非常有用:将值从一个对象复制到另一个对象

但是,我不知道如何修改 Jon Skeet 和 Marc Gravell 的 MiscUtil 中的代码来检查属性类型以及源是否为十进制且目标是否为 int,以调用 Convert.ToIn32()。

这是 MiscUtil 的代码,我想弄清楚如何修改:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace MiscUtil.Reflection
{
    /// <summary>
    /// Generic class which copies to its target type from a source
    /// type specified in the Copy method. The types are specified
    /// separately to take advantage of type inference on generic
    /// method arguments.
    /// </summary>
    public static class PropertyCopy<TTarget> where TTarget : class, new()
    {
        /// <summary>
        /// Copies all readable properties from the source to a new instance
        /// of TTarget.
        /// </summary>
        public static TTarget CopyFrom<TSource>(TSource source) where TSource : class
        {
            return PropertyCopier<TSource>.Copy(source);
        }

        /// <summary>
        /// Static class to efficiently store the compiled delegate which can
        /// do the copying. We need a bit of work to ensure that exceptions are
        /// appropriately propagated, as the exception is generated at type initialization
        /// time, but we wish it to be thrown as an ArgumentException.
        /// </summary>
        private static class PropertyCopier<TSource> where TSource : class
        {
            private static readonly Func<TSource, TTarget> copier;
            private static readonly Exception initializationException;

            internal static TTarget Copy(TSource source)
            {
                if (initializationException != null)
                {
                    throw initializationException;
                }
                if (source == null)
                {
                    throw new ArgumentNullException("source");
                }
                return copier(source);
            }

            static PropertyCopier()
            {
                try
                {
                    copier = BuildCopier();
                    initializationException = null;
                }
                catch (Exception e)
                {
                    copier = null;
                    initializationException = e;
                }
            }

            private static Func<TSource, TTarget> BuildCopier()
            {
                ParameterExpression sourceParameter = Expression.Parameter(typeof(TSource), "source");
                var bindings = new List<MemberBinding>();
                foreach (PropertyInfo sourceProperty in typeof(TSource).GetProperties())
                {
                    if (!sourceProperty.CanRead)
                    {
                        continue;
                    }
                    PropertyInfo targetProperty = typeof(TTarget).GetProperty(sourceProperty.Name);
                    if (targetProperty == null)
                    {
                        throw new ArgumentException("Property " + sourceProperty.Name + " is not present and accessible in " + typeof(TTarget).FullName);
                    }
                    if (!targetProperty.CanWrite)
                    {
                        throw new ArgumentException("Property " + sourceProperty.Name + " is not writable in " + typeof(TTarget).FullName);
                    }
                    if (!targetProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
                    {
                        throw new ArgumentException("Property " + sourceProperty.Name + " has an incompatible type in " + typeof(TTarget).FullName);
                    }
                    bindings.Add(Expression.Bind(targetProperty, Expression.Property(sourceParameter, sourceProperty)));
                }
                Expression initializer = Expression.MemberInit(Expression.New(typeof(TTarget)), bindings);
                return Expression.Lambda<Func<TSource,TTarget>>(initializer, sourceParameter).Compile();
            }
        }
    }
}

如果你有

public class Foo
{
    public decimal Value { get; set; }
}

public class Bar
{
    public int Value { get; set; }
}

然后与自动映射器(可从 NuGet 获得)您可以将对象 Foo 映射到对象 Bar,如下所示:

Mapper.CreateMap<Foo, Bar>();
Foo foo = new Foo() { Value = 10.5M };
var bar = Mapper.Map<Bar>(foo);
// bar.Value = 10;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将值从一个对象复制到另一个对象(不同类型) 的相关文章

随机推荐

  • 切入点不适用于通用接口

    我正在使用 Spring 框架 2 5 和它的 AOP 功能 我有一个切入点表达式 例如 Pointcut execution public org springframework batch item ItemReader read pu
  • 将 Task 类型保存到 String 会导致灾难性失败

    我正在尝试将我在 Canvas 上编写的 Ink 保存在一个类中 并使用在此找到的这两种方法重新加载它link private async Task
  • 如何在 Visual Studio C89 中按照其他代码声明可变长度数组 [重复]

    这个问题在这里已经有答案了 我知道在 VS 中所有变量都必须在块的顶部声明 但是如果我想要一个 VLA 即 如果我想做这样的事情 int result runalgorithm int vla result 上面的代码无效 因为vla必须在
  • 使用 CGridView、Yii 在 BELONGS_TO 模型列中搜索

    我有一个用于课程模型的 CGridView 小部件 this gt widget zii widgets grid CGridView array id gt lesson grid dataProvider gt model gt sea
  • 使用 SFML 库构建 CMake 项目

    我不明白如何使用构建 SFML 项目CMakeLists txt file 如果你有时间的话 请帮帮我 谢谢你 Details 我从官方网站下载了 SFML 库 https www sfml dev org index php 将其移至我的
  • 在 Windows 10 上使用 Python 关闭 WiFi?

    我一直在寻找一种使用脚本打开和关闭 wifi 的方法 我认为这可以通过进入飞行模式或其他方法来完成 当我在谷歌上搜索答案时 我找不到任何对 Windows 有用的东西 只找到 Android 甚至 macOS 的东西 有人有 2 个功能吗
  • 访问保存在类路径中的 Microsoft Access 数据库

    我正在尝试访问存储在类路径中的数据库 我已经安装了 ucanaccess 3 0 0 和所有必需的 jar 我的项目层次结构 这是我到目前为止的代码 public void login Connection conn try conn Dr
  • 是否可以仅为 d3 js 中树布局的子节点到子节点绘制虚线链接

    是否可以只为子节点到子子节点绘制虚线链接 父节点到其子节点应该是常规的连续链接 a b gt dashed links c d gt continues links a 有可能的 看看这个直播example 截图在这里 我创建了两种样式 一
  • 从数据帧的所有单元格值中删除前缀

    我有一个 pandas 数据框 如下所示 col1 col2 col3 field1 index1 value1 field2 index2 value2 field3 index3 value3 field1 index4 value4
  • 绕过 Delphi 7 中的 OutputDebugString?

    我想知道是否可以绕过 OutputDebugString 我希望 OutputDebugString 输出显示在 DebugView 中 而不是显示在内部 Delphi 事件查看器窗口中 但我找不到一种方法来告诉 Delphi 不要吞下 O
  • Payum Paypal Rest config_path

    我正在尝试使用 symfony 3 1 4 中的 payum 包来实现 paypal rest 支付 我需要在我的 Symfony 应用程序中运行 PayPal Plus 因此我读了这篇文章https github com Payum Pa
  • Restful PUT 方法的 ModelAttribute 未填充值 ( JSON )

    我正在使用 Spring MVC 构建一个完全安静的 Web 应用程序 当我有 PUT 方法时 我的 ModelAttribute 表单 bean 未填充 所有值均为 null 如果我使用 POST 方法 所有内容都会正确填充 我用 Pos
  • CMake - set_property 找不到 CACHE 变量

    免责声明 我知道this问题 然而 OP 的需求与我的不同 他真正想要的是将应用程序移植到 Linux 因此答案就在那一行 而不是回答我想知道的 错误的原因 我正在尝试按照中的说明在 CMake GUI 中创建一个下拉列表here and
  • 尝试在 C shell 中实现管道挂起并且未运行命令

    我正在尝试运行这个命令ps j more 我认为我已经正确设置了管道 但由于某种原因它只是挂起 我正在调用一个正在运行的 forkps j和第二个运行的叉子more并用管道将它们连接起来 由于某种原因 这仍然没有按预期工作 代码如下 def
  • 如何在 R 中使用 GenSA 函数进行数学约束

    我目前正在尝试使用模拟退火包 GenSA 来最小化以下功能 efficientFunction lt function v t v Cov Mat v 其中 Cov Mat 是从 4 个资产获得的协方差矩阵 v 是维度 4 的权重向量 我正
  • 通过在另一列中出现多个值来过滤组[重复]

    这个问题在这里已经有答案了 如同这个问题但又增加了皱纹 我想仅过滤在组的任何行的特定列中同时具有两个 或全部多个 值的行组 例如 假设我有这个数据框 df lt data frame Group LETTERS c 1 1 1 2 2 2
  • 当我关闭灯箱时停止播放视频

    我用这个建立了一个弹出窗口article看起来真的很好 这是我所做的
  • OpenCV 中的连接组件

    我正在寻找一个 OpenCV 函数 它可以找到连接的组件并对其执行一些任务 例如获取对象中的像素数 轮廓 像素列表等 OpenCV C 有没有类似于MatLab的regionprops的函数 从3 0版本开始 OpenCV有connecte
  • 不使用 sklearn 从数据构建混淆矩阵

    我正在尝试在不使用 sklearn 库的情况下构建混淆矩阵 我无法正确形成混淆矩阵 这是我的代码 def comp confmat currentDataClass 1 3 3 2 5 5 3 2 1 4 3 2 1 1 2 predict
  • 将值从一个对象复制到另一个对象(不同类型)

    我需要将一个对象的某些属性复制到另一个对象 但是 某些属性需要从十进制到整数的类型转换 我发现这个问题非常有用 将值从一个对象复制到另一个对象 但是 我不知道如何修改 Jon Skeet 和 Marc Gravell 的 MiscUtil