最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

What's the equivalent of Javascript's Object.assign() in C# - Stack Overflow

programmeradmin1浏览0评论

If I have a C# class

public class Foo
{
    public int? a { get; set; }
    public int? b { get; set; }
}

And two instances of that class

var foo1 = new Foo() { a = 1 };
var foo2 = new Foo() { b = 1 };

How could I copy the values from both objects to create a new instance of Foo that contained the values from both foo1 and foo2?

In Javascript this would be as simple as

var foo3 = Object.assign({}, foo1, foo2);

If I have a C# class

public class Foo
{
    public int? a { get; set; }
    public int? b { get; set; }
}

And two instances of that class

var foo1 = new Foo() { a = 1 };
var foo2 = new Foo() { b = 1 };

How could I copy the values from both objects to create a new instance of Foo that contained the values from both foo1 and foo2?

In Javascript this would be as simple as

var foo3 = Object.assign({}, foo1, foo2);
Share Improve this question edited Jan 10, 2023 at 8:30 Vivek Nuna 1 asked Nov 3, 2016 at 13:38 kavunkavun 3,3814 gold badges26 silver badges45 bronze badges 4
  • 6 This doesn't really make sense in C# since foo1 and foo2 will both always have values for a and b. So you would just be copying the values of foo2 into the target. You could make a and b nullable and write a version which only sets non-null values. – Lee Commented Nov 3, 2016 at 13:42
  • I don't think there is anything like that in .NET/C#. You could use reflection to create functionality like that. Also have a look at there, this is basically the same question: stackoverflow.com/questions/26156577/… – egonr Commented Nov 3, 2016 at 13:45
  • @Lee's suggestion seems a good fit for what you are describing. you could then do an assignment like this var foo3 = new Foo() {a = foo1.a ?? foo2.a, b = foo1.b ?? foo2.b }; – Theo Commented Nov 3, 2016 at 13:49
  • good point @Lee, I'll update my example to include nullable properties to be more realistic. – kavun Commented Nov 3, 2016 at 14:19
Add a comment  | 

4 Answers 4

Reset to default 9

you could create a method which merges objects via reflection. But beware, this is slow an can generally not used in C#.

Care must be taken to skip "empty" properties. In your case these are value types. In my example implementation, every property is skipped, if its the default value of that type (for int this is 0):

public T CreateFromObjects<T>(params T[] sources)
    where T : new()
{
    var ret = new T();
    MergeObjects(ret, sources);

    return ret;
}

public void MergeObjects<T>(T target, params T[] sources)
{
    Func<PropertyInfo, T, bool> predicate = (p, s) =>
    {
        if (p.GetValue(s).Equals(GetDefault(p.PropertyType)))
        {
            return false;
        }

        return true;
    };

    MergeObjects(target, predicate, sources);
}

public void MergeObjects<T>(T target, Func<PropertyInfo, T, bool> predicate, params T[] sources)
{
    foreach (var propertyInfo in typeof(T).GetProperties().Where(prop => prop.CanRead && prop.CanWrite))
    {
        foreach (var source in sources)
        {
            if (predicate(propertyInfo, source))
            {
                propertyInfo.SetValue(target, propertyInfo.GetValue(source));
            }
        }
    }
}

private static object GetDefault(Type type)
{
    if (type.IsValueType)
    {
        return Activator.CreateInstance(type);
    }
    return null;
}

usage:

var foo3 = CreateFromObjects(foo1, foo2);

There is no direct method for this, But you can fulfil your requirement this way.

var foo3 = new Foo() {a = foo1.a, b = foo2.b };

Vivek's answer is the correct one. Because Object.Assign is part of the larger Inheritance vs Composition discussion. This is not so simple in javascript, where you need Object.Assign, but in C# you can compose a class in your own class by just instantiating it and making it a property. You really do it all the time.

Javascript with it's prototypal inheritance, you're really just linking objects. So inheritance (classical) does not exists there.

Check this video, it's very enlightening: Inheritance vs Composition

using Newtonsoft.Json;
.
.
.

var newFoo = JsonConvert.DeserializeObject<Foo>(JsonConvert.SerializeObject(oldFoo));

regards, Oli

发布评论

评论列表(0)

  1. 暂无评论