Is there a jQuery extend in c#? - c#

var _Contact = new ContactLstModel {
ContactName="xxxxxx",
EmailAddr="yyyyyy",
ContactNo="ddddddd",
SelectedContactType="dddd"
};
var _ContactOption= new ContactLstModel{
ContactType= new List<SelectListItem>(){
new SelectListItem{
Text="sss",Value="ddd"
}
}
};
as you can see both are of the same model ContactLstModel. Now how do I combine both into one?
Like in jQuery, we have $.extend(dest,source);
Is there an equivalent in C#?

There is not a built-in equivalent of $.extend in C# and .NET 4.5.
However you can find many examples of people trying to achieve that kind of behavior using reflection in .NET. There are others who use serialization (JSON.NET etc.) to achieve similar behaviors . Another approach would be to use IOC containers like Automapper.
Here is an example how to merge your first object into the second object using Automapper IOC:
var expr = Mapper.CreateMap<ContactLstModel, ContactLstModel>().ForMember("ContactType", (conf) => { conf.Ignore(); });
var merged = Mapper.Map<ContactLstModel, ContactLstModel>(_Contact, _ContactOption);
With Automapper you can control how to map each single property from source to destination.
If you don't want external library dependencies, and want full control you can use a pure Reflection approach.
For example you could use something similar as the CopyValues method from this link and merge the second object properties with the first one using reflection.
CopyValues<ContactLstModel>(_Contact, _ContactOption);
So this line of code will copy the ContactType property values from the second object into the first one.
CopyValues uses reflection to loop through the properties of the objects:
public static void CopyValues<T>(T target, T source)
{
Type t = typeof(T);
var properties = t.GetProperties().Where(prop => prop.CanRead && prop.CanWrite);
foreach (var prop in properties)
{
var value = prop.GetValue(source, null);
if (value != null)
prop.SetValue(target, value, null);
}
}
Of course this does not support everything jquery extend does (merging, shallow and deep cloning into a new object etc.), but it can satisfy your current needs. You can extend on these principles and build a more comprehensive solution.
However have in mind that C# is not a language like Javascript, and the cost of doing reflection is much higher in C#, while in Javascript the properties of a prototype can be listed with a cheap for-in iteration, or with a call to Object.keys().

You could do it with an extension method:
public static class ContactModelExtensions {
public static ContactModel Extend(this ContactModel first, ContactModel replacement) {
if (!replacement.ContactsName.IsNullOrEmpty()) // or whatever criteria you want
{
first.ContactsName = replacement.ContactsName;
}
// similar assignment for all other properties
return first; // since we return the first one, properties not set in override
// will be untouched
}
}
Now, you can just
var extendedContact = _Contact.Extend(_ContactOptions);
to get it done.

You can use some frameworks for do it. For example with ValueInjecter:
public class NoNullsInjection : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name
&& c.SourceProp.Value != null;
}
}
class A
{
public string a { get; set; }
public string b { get; set; }
}
static void Main(string[] args)
{
A a1 = new A() { a = "123" };
A a2 = new A() { b = "456" };
A c = new A();
c.InjectFrom(new NoNullsInjection(),a1,a2);
// "c" now have a="123", b="456"
}

Related

Convert class object to class index

Class Person {
int Id
string Name
string Address
// etc
}
instead of accessing it like Person.Id, Person.Name, Person.Address. I want to access it via index just like Person['Id'], Person['Name']. Is there any codegen or linq conversion for this.
You can use Json.NET's JObject class
Person p = new Person() { Id = 1, Address = "A", Name = "B" };
var obj = JObject.FromObject(p);
Console.WriteLine(obj["Id"]); //1
This is a pure C# implementation:
class Program
{
static void Main(string[] args)
{
Person person = new Person
{
Id = 1,
Name = "test",
Address = "tost"
};
Console.WriteLine(person["Id"]);
person["Id"] = 5;
Console.WriteLine(person["Id"]);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public object this[string propertyName]
{
get
{
return this.GetType().GetProperty(propertyName).GetValue(this);
}
set
{
this.GetType().GetProperty(propertyName).SetValue(this, value);
}
}
}
Output:
1
5
Important note:
I would never recommend to use this in a production environment, if you want to use an handly implemented system, atleast you should handle types and properties extractions to avoid consuming more memory than needed and exceeding overheads.
Using reflection and indexers:
public class ExampleClass{
public object this[string name]
{
get
{
var properties = typeof(ExampleClass)
.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
if (property.Name == name && property.CanRead)
return property.GetValue(this, null);
}
throw new ArgumentException("Can't find property");
}
set {
return;
}
}
}
An indexer won't make data comparison any easier. I suspect the real question is how to handle data in C# the same way Python's DataFrames work. ADO.NET provides the DataTable class since .NET 1.0. It's meant more for database processing than data analysis, altough it does support operations like searching, merging and diffing.
For data anlysis, the new Microsoft.Data.Analysis package provides the DataFrame class.
That said, to read properties by name, you'll have to use Reflection, an expensive operation. One way to make this cheaper is to cache type and property descriptors. Instead of writing the code yourself though, you can use Marc Gravel's FastMember library that does just that. With this, you can create a TypeAccessor or ObjectAccessor type and read properties by name, eg :
var wrapped = ObjectAccessor.Create(obj);
string propName = // something known only at runtime
Console.WriteLine(wrapped[propName]);
If you want to read from multiple objects, you'll need a TypeAccessor :
var accessor = TypeAccessor.Create(type);
string propName = // something known only at runtime
while( /* some loop of data */ )
{
accessor[obj, propName] = rowValue;
}
The library isn't that big. If you aren't allowed to use NuGet packages, you could copy the code into your project.

the easest way of findind the difference of two objects of the same class [duplicate]

The project I'm working on needs some simple audit logging for when a user changes their email, billing address, etc. The objects we're working with are coming from different sources, one a WCF service, the other a web service.
I've implemented the following method using reflection to find changes to the properties on two different objects. This generates a list of the properties that have differences along with their old and new values.
public static IList GenerateAuditLogMessages(T originalObject, T changedObject)
{
IList list = new List();
string className = string.Concat("[", originalObject.GetType().Name, "] ");
foreach (PropertyInfo property in originalObject.GetType().GetProperties())
{
Type comparable =
property.PropertyType.GetInterface("System.IComparable");
if (comparable != null)
{
string originalPropertyValue =
property.GetValue(originalObject, null) as string;
string newPropertyValue =
property.GetValue(changedObject, null) as string;
if (originalPropertyValue != newPropertyValue)
{
list.Add(string.Concat(className, property.Name,
" changed from '", originalPropertyValue,
"' to '", newPropertyValue, "'"));
}
}
}
return list;
}
I'm looking for System.IComparable because "All numeric types (such as Int32 and Double) implement IComparable, as do String, Char, and DateTime." This seemed the best way to find any property that's not a custom class.
Tapping into the PropertyChanged event that's generated by the WCF or web service proxy code sounded good but doesn't give me enough info for my audit logs (old and new values).
Looking for input as to if there is a better way to do this, thanks!
#Aaronaught, here is some example code that is generating a positive match based on doing object.Equals:
Address address1 = new Address();
address1.StateProvince = new StateProvince();
Address address2 = new Address();
address2.StateProvince = new StateProvince();
IList list = Utility.GenerateAuditLogMessages(address1, address2);
"[Address] StateProvince changed from
'MyAccountService.StateProvince' to
'MyAccountService.StateProvince'"
It's two different instances of the StateProvince class, but the values of the properties are the same (all null in this case). We're not overriding the equals method.
IComparable is for ordering comparisons. Either use IEquatable instead, or just use the static System.Object.Equals method. The latter has the benefit of also working if the object is not a primitive type but still defines its own equality comparison by overriding Equals.
object originalValue = property.GetValue(originalObject, null);
object newValue = property.GetValue(changedObject, null);
if (!object.Equals(originalValue, newValue))
{
string originalText = (originalValue != null) ?
originalValue.ToString() : "[NULL]";
string newText = (newText != null) ?
newValue.ToString() : "[NULL]";
// etc.
}
This obviously isn't perfect, but if you're only doing it with classes that you control, then you can make sure it always works for your particular needs.
There are other methods to compare objects (such as checksums, serialization, etc.) but this is probably the most reliable if the classes don't consistently implement IPropertyChanged and you want to actually know the differences.
Update for new example code:
Address address1 = new Address();
address1.StateProvince = new StateProvince();
Address address2 = new Address();
address2.StateProvince = new StateProvince();
IList list = Utility.GenerateAuditLogMessages(address1, address2);
The reason that using object.Equals in your audit method results in a "hit" is because the instances are actually not equal!
Sure, the StateProvince may be empty in both cases, but address1 and address2 still have non-null values for the StateProvince property and each instance is different. Therefore, address1 and address2 have different properties.
Let's flip this around, take this code as an example:
Address address1 = new Address("35 Elm St");
address1.StateProvince = new StateProvince("TX");
Address address2 = new Address("35 Elm St");
address2.StateProvince = new StateProvince("AZ");
Should these be considered equal? Well, they will be, using your method, because StateProvince does not implement IComparable. That's the only reason why your method reported that the two objects were the same in the original case. Since the StateProvince class does not implement IComparable, the tracker just skips that property entirely. But these two addresses are clearly not equal!
This is why I originally suggested using object.Equals, because then you can override it in the StateProvince method to get better results:
public class StateProvince
{
public string Code { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
StateProvince sp = obj as StateProvince;
if (object.ReferenceEquals(sp, null))
return false;
return (sp.Code == Code);
}
public bool Equals(StateProvince sp)
{
if (object.ReferenceEquals(sp, null))
return false;
return (sp.Code == Code);
}
public override int GetHashCode()
{
return Code.GetHashCode();
}
public override string ToString()
{
return string.Format("Code: [{0}]", Code);
}
}
Once you've done this, the object.Equals code will work perfectly. Instead of naïvely checking whether or not address1 and address2 literally have the same StateProvince reference, it will actually check for semantic equality.
The other way around this is to extend the tracking code to actually descend into sub-objects. In other words, for each property, check the Type.IsClass and optionally the Type.IsInterface property, and if true, then recursively invoke the change-tracking method on the property itself, prefixing any audit results returned recursively with the property name. So you'd end up with a change for StateProvinceCode.
I use the above approach sometimes too, but it's easier to just override Equals on the objects for which you want to compare semantic equality (i.e. audit) and provide an appropriate ToString override that makes it clear what changed. It doesn't scale for deep nesting but I think it's unusual to want to audit that way.
The last trick is to define your own interface, say IAuditable<T>, which takes a second instance of the same type as a parameter and actually returns a list (or enumerable) of all of the differences. It's similar to our overridden object.Equals method above but gives back more information. This is useful for when the object graph is really complicated and you know you can't rely on Reflection or Equals. You can combine this with the above approach; really all you have to do is substitute IComparable for your IAuditable and invoke the Audit method if it implements that interface.
This project on github checks nearly any type of property and can be customized as you need.
You might want to look at Microsoft's Testapi It has an object comparison api that does deep comparisons. It might be overkill for you but it could be worth a look.
var comparer = new ObjectComparer(new PublicPropertyObjectGraphFactory());
IEnumerable<ObjectComparisonMismatch> mismatches;
bool result = comparer.Compare(left, right, out mismatches);
foreach (var mismatch in mismatches)
{
Console.Out.WriteLine("\t'{0}' = '{1}' and '{2}'='{3}' do not match. '{4}'",
mismatch.LeftObjectNode.Name, mismatch.LeftObjectNode.ObjectValue,
mismatch.RightObjectNode.Name, mismatch.RightObjectNode.ObjectValue,
mismatch.MismatchType);
}
Here a short LINQ version that extends object and returns a list of properties that are not equal:
usage: object.DetailedCompare(objectToCompare);
public static class ObjectExtensions
{
public static List<Variance> DetailedCompare<T>(this T val1, T val2)
{
var propertyInfo = val1.GetType().GetProperties();
return propertyInfo.Select(f => new Variance
{
Property = f.Name,
ValueA = f.GetValue(val1),
ValueB = f.GetValue(val2)
})
.Where(v => !v.ValueA.Equals(v.ValueB))
.ToList();
}
public class Variance
{
public string Property { get; set; }
public object ValueA { get; set; }
public object ValueB { get; set; }
}
}
You never want to implement GetHashCode on mutable properties (properties that could be changed by someone) - i.e. non-private setters.
Imagine this scenario:
you put an instance of your object in a collection which uses GetHashCode() "under the covers" or directly (Hashtable).
Then someone changes the value of the field/property that you've used in your GetHashCode() implementation.
Guess what... your object is permanently lost in the collection since the collection uses GetHashCode() to find it! You've effectively changed the hashcode value from what was originally placed in the collection. Probably not what you wanted.
Liviu Trifoi solution: Using CompareNETObjects library.
GitHub - NuGet package - Tutorial.
I think this method is quite neat, it avoids repetition or adding anything to classes. What more are you looking for?
The only alternative would be to generate a state dictionary for the old and new objects, and write a comparison for them. The code for generating the state dictionary could reuse any serialisation you have for storing this data in the database.
The my way of Expression tree compile version. It should faster than PropertyInfo.GetValue.
static class ObjDiffCollector<T>
{
private delegate DiffEntry DiffDelegate(T x, T y);
private static readonly IReadOnlyDictionary<string, DiffDelegate> DicDiffDels;
private static PropertyInfo PropertyOf<TClass, TProperty>(Expression<Func<TClass, TProperty>> selector)
=> (PropertyInfo)((MemberExpression)selector.Body).Member;
static ObjDiffCollector()
{
var expParamX = Expression.Parameter(typeof(T), "x");
var expParamY = Expression.Parameter(typeof(T), "y");
var propDrName = PropertyOf((DiffEntry x) => x.Prop);
var propDrValX = PropertyOf((DiffEntry x) => x.ValX);
var propDrValY = PropertyOf((DiffEntry x) => x.ValY);
var dic = new Dictionary<string, DiffDelegate>();
var props = typeof(T).GetProperties();
foreach (var info in props)
{
var expValX = Expression.MakeMemberAccess(expParamX, info);
var expValY = Expression.MakeMemberAccess(expParamY, info);
var expEq = Expression.Equal(expValX, expValY);
var expNewEntry = Expression.New(typeof(DiffEntry));
var expMemberInitEntry = Expression.MemberInit(expNewEntry,
Expression.Bind(propDrName, Expression.Constant(info.Name)),
Expression.Bind(propDrValX, Expression.Convert(expValX, typeof(object))),
Expression.Bind(propDrValY, Expression.Convert(expValY, typeof(object)))
);
var expReturn = Expression.Condition(expEq
, Expression.Convert(Expression.Constant(null), typeof(DiffEntry))
, expMemberInitEntry);
var expLambda = Expression.Lambda<DiffDelegate>(expReturn, expParamX, expParamY);
var compiled = expLambda.Compile();
dic[info.Name] = compiled;
}
DicDiffDels = dic;
}
public static DiffEntry[] Diff(T x, T y)
{
var list = new List<DiffEntry>(DicDiffDels.Count);
foreach (var pair in DicDiffDels)
{
var r = pair.Value(x, y);
if (r != null) list.Add(r);
}
return list.ToArray();
}
}
class DiffEntry
{
public string Prop { get; set; }
public object ValX { get; set; }
public object ValY { get; set; }
}

Compact syntax to create tree structure in C#

I would like to create a somewhat complex tree structure in code, in a concise manner. Right now I'm using this (simplified):
var root = new Tree();
var c1 = root.Add("1");
var c2 = root.Add("2");
var c21 = c2.Add("2-1");
var c22 = c2.Add("2-2");
//...
Average node width is 4, tree height is about 5, so the above process is very tedious, not to mention poorly maintainable.
Let us assume the nodes are not accessed by name later. The tree/node classes can be adjusted as necessary. Performance can be disregarded. Creation via XML or similar is not possible (the node constructor is quite a bit more complicated in reality).
What I'm looking for is something like the following, but I'm not sure how this could be implemented in C#. In Java, this would be possible via anonymous classes, which cannot be used for this purpose in C#.
var root = new Tree() {
Add("1");
Add("2") {
Add("2-1");
Add("2-2");
};
}
The best solution I could think of would use run-on declaration similar to the following, which I think is poorly maintainable:
// AddXxx returns the added node
var root = new Tree()
.Add("1")
.AddSibling("2")
.Add("2-1")
.AddSibling("2-2")
.AddParent("3")
.Add("3-1")
Or alternatively:
// Add now always adds a sibling, Children/Parent steps up/down in the hierarchy
var root = new Tree()
.Children
.Add("1")
.Add("2")
.Children
.Add("2-1")
.Add("2-2")
.Parent
.Add("3")
.Children
.Add("3-1")
I will do something like this:
public class Tree
{
public string Name { get; private set; }
public List<Tree> Trees { get; private set; }
public Tree(string name)
{
this.Name = name;
this.Trees = new List<Tree>();
}
public Tree(string name, params Tree[] nodes)
: this(name)
{
if (nodes == null || !nodes.Any()) return;
Trees.AddRange(nodes);
}
}
Then use it like this:
var trees = new List<Tree>
{
new Tree("1"),
new Tree("2",
new Tree("2-1"),
new Tree("2-2",
new Tree("2-2-1"),
new Tree("2-2-1")
)
),
new Tree("3",
new Tree("3-1")
)
};
I was inspired to this by XElement constructor which faciltate XML nodes creation with more readability. If you are working with XML then I recommend to use that class.
You can use a collection initializer:
class Node : IEnumerable<Node> // implement interface to taste
{
public Node(string name)
{
...
}
public void Add(Node n)
{
...
}
}
var root = new Node("x")
{ // Each item in this {} is passed to Add
new Node("y-1")
{
new Node("z-1"),
new Node("z-2")
},
new Node("y-2")
};
A conventional way to do this is with a collection initalizer. I'm not a fan, because this means you need to implement an Add method, and that means you need to implement a mutable Tree interface, which is (IMHO) a hassle that makes many conventional tree algorithms unsafe. (you could also implement freezable TreeBuilder, but that's just as much hassle).
I prefer to list all tree nodes at construction time, and with C# 6's using static you can do this quite cleanly.
Linqpad query:
void Main()
{
Node("test",
Node("kid"),
Node("kid2",
Node("grandchild")
),
Node("kid3",
Node("grandchild2"),
Node("grandchild3")
)
)
.ToString().Dump();
}
public static class Tree
{
public static TreeNode<T> Node<T>(T val, params TreeNode<T>[] kids)
=> new TreeNode<T>(val, kids);
}
public struct TreeNode<T>
{
public readonly T NodeValue;
public readonly IReadOnlyList<TreeNode<T>> Kids;
public TreeNode(T val, TreeNode<T>[] kids)
{
NodeValue = val;
Kids = kids;
}
public override string ToString()
=> $"\n{NodeValue}:{string.Join("", Kids).Replace("\n", "\n ")}";
}
which prints:
test:
kid:
kid2:
grandchild:
kid3:
grandchild2:
grandchild3:
Note that reinterpreting an array as IReadOnlyList doesn't protect you from nasty callers that mutate params arrays after constructions, which is likely fine in a normal project, but possibly not so hot for a public api - YMMV.

.NET: Is there a Class to copy properties of one class to another

I wrote a function that copies the properties of one class to another so make a copy of an object.
So something like
MyObject myObject = myOtherObject.MyCustomCopy(myObject)
where myObject and myOtherObject are of the same type. I do it by bascually doing
myObject.prop1 = myOtherObject.prop1
myObject.prop2 = myOtherObject.prop2
myObject.prop3 = myOtherObject.prop3
return myObject
I am pretty sure in the past I used a .NET object that automaticaly did this, by reflection I guess, but can't remember it ... or an I imagining that such a method exists?
Yes I'm aware of auto mapper but i was sure (not so much now) that there is a .NET object that does the job. Maybe not!
You may take a look at AutoMapper.
public static class ext
{
public static void CopyAllTo<T>(this T source, T target)
{
var type = typeof(T);
foreach (var sourceProperty in type.GetProperties())
{
var targetProperty = type.GetProperty(sourceProperty.Name);
targetProperty.SetValue(target, sourceProperty.GetValue(source, null), null);
}
foreach (var sourceField in type.GetFields())
{
var targetField = type.GetField(sourceField.Name);
targetField.SetValue(target, sourceField.GetValue(source));
}
}
}
You should use AutoMapper it was built for this job.
System.Object.MemberwiseClone()
Try description in this link:
.NET Reflection - Copy Class Properties
This code should work for basic property types, not sure how it'll go for anything complex (lists, arrays, custom classes). Should be a starting point though:
public class MyClass
{
public int A { get; set; }
public string B { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
MyClass orig = new MyClass() { A = 1, B = "hello" };
MyClass copy = new MyClass();
PropertyInfo[] infos = typeof(MyClass).GetProperties();
foreach (PropertyInfo info in infos)
{
info.SetValue(copy, info.GetValue(orig, null), null);
}
Console.WriteLine(copy.A + ", " + copy.B);
}
I know the OP did not ask for a Type to another Type but my variant is one I use for DI in startup.cs for mismatches in configurations between cloud and local dev environment. My local class generally uses a Interface class behind the scenes to map the configurations. Then I use this method to copy properties where they match in name only. I am not checking property types since these are configurations. AutoMapper was suggested. I don't use AutoMapper because we are restricted by U.S. DOD to certain providers. Getting an ATO is hard enough just using .NET, we don't need any more grief.
using System.Linq;
public static class PropertyCopy
{
public static void CopyAllTo<T,T1>(this T source, T1 target)
{
var type = typeof(T);
var type1 = typeof(T1);
foreach (var sourceProperty in type.GetProperties())
{
foreach (var targetProperty in type1.GetProperties()
.Where(targetProperty => sourceProperty.Name == targetProperty.Name)
.Where(targetProperty => targetProperty.SetMethod != null))
{
targetProperty.SetValue(target, sourceProperty.GetValue(source, null), null);
}
}
foreach (var sourceField in type.GetFields())
{
foreach (var targetField in type1.GetFields()
.Where(targetField => sourceField.Name == targetField.Name))
{
targetField.SetValue(target, sourceField.GetValue(source));
}
}
}
}
In very simple terms: As we know Classes are reference types in C#.NET i.e. when we create a object of a class such as
Customer C1=new Customer();
C1.Id=1;
C1.Name="Rakesh";
Then C1(Reference variable) is stored on memory stack and object new Customer() is stored on Heap.
Hence when we copy a class into another class which is basically your question you can do something like below:
Customer C2=C1;
Doing above will copy the C1 Reference variable into C2 But why I wrote about Stack and Heap because using C2 reference variable you can change the object properties being both C1 and C2 pointing to same object in HEAP.Something Like
C2.Id=1;
C2.Name="Mukesh";
Now if you will try to access C1.Name you will see it is changed to "Mukesh".
you can use JsonConvert like this:
string jsonString = JsonConvert.SerializeObject(MyObject);
MyClass object = JsonConvert.DeserializeObject<MyClass>(jsonString);

c# copy constructor generator

I want to copy values from one object to another object. Something similar to pass by value but with assignment.
For example:
PushPin newValPushPin = oldPushPin; //I want to break the reference here.
I was told to write a copy constructor for this. But this class has a lot of properties, it will probably take an hour to write a copy constructor by hand.
Is there a better way to assign an object to another object by value?
If not, is there a copy constructor generator?
Note: ICloneable is not available in Silverlight.
If you can mark the object that is to be cloned as Serializable then you can use in-memory serialization to create a copy. Check the following code, it has the advantage that it will work on other kinds of objects as well and that you don't have to change your copy constructor or copy code each time an property is added, removed or changed:
class Program
{
static void Main(string[] args)
{
var foo = new Foo(10, "test", new Bar("Detail 1"), new Bar("Detail 2"));
var clonedFoo = foo.Clone();
Console.WriteLine("Id {0} Bar count {1}", clonedFoo.Id, clonedFoo.Bars.Count());
}
}
public static class ClonerExtensions
{
public static TObject Clone<TObject>(this TObject toClone)
{
var formatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
formatter.Serialize(memoryStream, toClone);
memoryStream.Position = 0;
return (TObject) formatter.Deserialize(memoryStream);
}
}
}
[Serializable]
public class Foo
{
public int Id { get; private set; }
public string Name { get; private set; }
public IEnumerable<Bar> Bars { get; private set; }
public Foo(int id, string name, params Bar[] bars)
{
Id = id;
Name = name;
Bars = bars;
}
}
[Serializable]
public class Bar
{
public string Detail { get; private set; }
public Bar(string detail)
{
Detail = detail;
}
}
There is a protected member called "MemberwiseClone", you can write this in your class...
public MyClass Clone(){
return (MyClass)this.MemberwiseClone();
}
then you can access..
MyClass newObject = oldObject.Clone();
The only way (that I'm aware of) to do this, and do it correctly, is to implement the copy yourself. Take for example:
public class FrobAndState
{
public Frob Frobber { get; set;}
public bool State { get; set; }
}
public class Frob
{
public List<int> Values { get; private set; }
public Frob(int[] values)
{
Values = new List<int>(values);
}
}
In this example you'd need to know how Frob was implemented, i.e. the fact that you need to call the constructor to create a copy of it as Values is read-only, to be able to make a copy of a given instance of FrobAndState.
Also - you couldn't just implement FrobAndState.Copy thusly:
public class FrobAndState
{
// ... Properties
public FrobAndState Copy()
{
var new = new FrobAndState();
new.State = this.State;
new.Frobber = this.Frobber;
}
}
Because both the instance of FrobAndState that you called .Copy() on, and the new instance would both have a reference to the same instance of Frobber.
In short, copying things is hard and any Copy implementation is difficult to get right.
C# does not have a copy constructor. There are different ways to tackle this. At the OOP level you could use inheritance or aggregation. AutoMapper might also be worth a try.
I want to copy values from one object
to another object. Something similiar
to pass by value but with assignment.
What do you mean by "with assignment"? If you mean that you want people to be able to say:
a = b;
And for you to define what = means, the only way you can do that in C# is if b is a different type to a and you've defined an implicit conversion (or more tenuously, if a stands for something of the form x.Y where Y is a property with a setter). You can't override = for a simple assignment between identical types in C#.
I was told to write a copy constructor
for this. But this class has alot of
properties, it will probably take an
hour to write a copy constructor by
hand.
If that's really true, then I would guess that you have a different problem. Your class is too big.
If you make your class Serializable you could Serialize it to a MemoryStream and Deserialize to a new instance.
If you want copy-on-assignment you should be using a struct instead of a class. But be careful, it is easy to make subtle mistakes. It is highly recommended that all stucts be immmutable to reduce the chance for error.
Though, this may not answer your question directly, but to add a cent; usually the term Clone is linked with shallow copy(referenced objects). To have a deep copy, I believe you will need to look into the some creational pattern(prototype?). The answer to this question might help.
You implement Justin Angel's method of cloning objects in Silverlight
using System;
using System.Reflection;
using System.Windows;
namespace JustinAngelNet.Silverlight.Framework
{
public static class SilverlightExtensions
{
public static T Clone<T>(T source)
{
T cloned = (T) Activator.CreateInstance(source.GetType());
foreach (PropertyInfo curPropInfo in source.GetType().GetProperties())
{
if (curPropInfo.GetGetMethod() != null
&& (curPropInfo.GetSetMethod() != null))
{
// Handle Non-indexer properties
if (curPropInfo.Name != "Item")
{
// get property from source
object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] {});
// clone if needed
if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject) getValue);
// set property on cloned
if (getValue != null)
curPropInfo.GetSetMethod().Invoke(cloned, new object[] {getValue});
}
// handle indexer
else
{
// get count for indexer
int numberofItemInColleciton =
(int)
curPropInfo.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(source, new object[] {});
// run on indexer
for (int i = 0; i < numberofItemInColleciton; i++)
{
// get item through Indexer
object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] {i});
// clone if needed
if (getValue != null && getValue is DependencyObject)
getValue = Clone((DependencyObject) getValue);
// add item to collection
curPropInfo.ReflectedType.GetMethod("Add").Invoke(cloned, new object[] {getValue});
}
}
}
}
return cloned;
}
}
}
Then you can do this
MyClass newObject = SilverlightExtensions.Clone(oldObject);

Categories

Resources