Cloning an array of objects which implement ICloneable - c#

public class MyStuff : ICloneable
{
public int A {get;set;}
public int B {get;set;}
public object Clone()
{
MyStuff Copy = (MyStuff)MemberwiseClone();
return Copy;
}
}
Now lets assume i have an array of MyStuff
MyStuff[] MyStuffObjs = PopulateMyStuff();
What is the quickest/easiest way to create a clone of MyStuffObjs implementing the Clone method?
I know i can iterate through the collection and copy each one.
List<MyStuff> NewStuff = new List<MyStuff>();
foreach(var Stuff in MyStuffObjs)
{
NewStuff.Add(Stuff.Clone());
}
return NewStuff.ToArray();
Surely there is a better way?

You can use Linq for that:
return MyStuffObjs.Select(item => (MyStuff)item.Clone()).ToArray();
You can even create a helper method like this
public static class MyExtensions
{
public static T[] DeepClone<T>(this T[] source) where T : ICloneable
{
return source.Select(item => (T)item.Clone()).ToArray();
}
}
and use it as follows
return MyStuffObjs.DeepClone();

Just Select/ToArray would be shorter, but really there is nothing significantly better than iterating over all items and calling Clone.
Shorter code:
return MyStuffObjs.Select( x=> x.Clone()).ToArray();
A bit faster code - pre-allocate array instead of using list:
MyStuff[] cloned = new MyStuff[MyStuffObjs.Length];
for (var i = 0; i < cloned.Lenght; i++)
{
cloned[i] = MyStuffObjs[i].Clone();
}

Related

Given a custom generic class that stores a List<T> how do I prevent adding an object of type T more than once to the List<T>? [duplicate]

This question already has answers here:
What does Collection.Contains() use to check for existing objects?
(6 answers)
Closed 1 year ago.
So this is the code that I have tried, but it adds the same object more than once:
namespace TestComparison
{
public interface IAddable
{
int RandomIntValue { get; set; } // often Times this value will repeat.
}
public class AdditionManager<T> where T : IAddable
{
private List<T> addables;
public AdditionManager()
{
addables = new List<T>();
}
public void Add(T _addable)
{
if (!addables.Contains(_addable))
{
addables.Add(_addable);
}
}
}
public class TestAddable : IAddable
{
public int RandomIntValue { get; set; }
public Data UniqueData = new Data() { UniqueId = 10023 }; // This is what really make each item unique
}
public class Data
{
public int UniqueId { get; set; }
}
}
I've heard about the IEqualityComparer and I have implemented it in non-generic classes, but I'm not quite sure how to implement it here.
Your problem indeed seems to be related to a missing IEqualityComparer.
Imagine the following:
class TestClass
{
public int x;
}
class Program
{
static void Main(string[] args)
{
TestClass nine = new TestClass() { x = 9 };
TestClass twelve = new TestClass() { x = 12 };
TestClass anotherNine = new TestClass() { x = 9 };
Console.WriteLine(nine == twelve);
Console.WriteLine(nine == anotherNine);
}
}
What will this program output? The "surprising" answer is that it outputs False two times. This is because the objects are compared to each other, not the members of the objects. To achieve an actual value comparison which will compare the objects by their content instead of their reference you need to consider quite a few things. If you want to be really complete, you need IComparable, IEquality, GetHashcode etc etc. It's very easy to make a mistake there.
But since C# 9.0 there's a new type which can be used instead of class. The type is record. This new record type has all the stuff I mentioned implemented by default. If you want to go the long route, I suggest you to look into the new record type and what it actually is.
This means all you need to do is change the type of your TestAddable and Data from class to record and you should be fine.
You can use dependency injection to provide you with generic implementation. Doing so you'll need to provide the custom IEqualityComparer<T> implementation that you want at the point of generic object's construction.
public class AdditionManager<T> where T : IAddable
{
private List<T> addables;
private IEqualityComparer<T> comparer;
public AdditionManager()
: this (EqualityComparer<T>.Default)
{ }
public AdditionManager(IEqualityComparer<T> _comparer)
{
addables = new List<T>();
comparer = _comparer;
}
public void Add(T _addable)
{
if (!addables.Contains(_addable, comparer))
{
addables.Add(_addable);
}
}
}
However, if you are looking for you list of addables to be unique based on some constraint, I would not use the above implementation for performance reasons. As the List<T>.Contains check will become slower as the list grows larger.
If the order of the list does not matter change your List<T> to a HashSet<T>. HashSet<T>.Contains will be just as quick as a Dictionary<TKey, TValue> lookup. But this call can be avoided altogether with HashSet<T> as the Add call will first check to see if the item is in the set before adding it, and return true or false to indicate it was added or not`
So if the order of addables is of not concern, then I would use the following implementation.
public class AdditionManager<T> where T : IAddable
{
private HashSet<T> addables;
public AdditionManager()
: this(EqualityComparer<T>.Default)
{ }
public AdditionManager(IEqualityComparer<T> _comparer)
{
addables = new HashSet<T>(_comparer);
}
public void Add(T _addable)
{
// will not add the item to the HashSet if it is already present
addables.Add(_addable);
}
}
If you need to maintain the order of addables then I suggest maintaining the list of objects in both a HashSet<T> and List<T>. This will provide you with the performance of the above implementation, but maintain the addition order on your items. In this implementation any of the operations you need to perform, do them against the List<T> and only use the HashSet<T> to make sure the item isn't already present when adding to List<T> If you are going to have some type of Remove operation, make sure to remove the item from both the HashSet<T> and List<T>
public class AdditionManager<T> where T : IAddable
{
private HashSet<T> set;
private List<T> list;
public AdditionManager()
: this(EqualityComparer<T>.Default)
{ }
public AdditionManager(IEqualityComparer<T> _comparer)
{
set = new HashSet<T>(_comparer);
list = new List<T>();
}
public void Add(T _addable)
{
if (set.Add(_addable))
list.Add(_addable);
}
}
To create this object using TestAddable you'll need an IEqualityComparer<TestAddable> like the following. As others have suggested, the field(s) you are doing your comparison on should be made immutable, as a mutable key is going to cause bugs.
public class TestAddableComparer : IEqualityComparer<TestAddable>
{
public bool Equals(TestAddable x, TestAddable y)
{
return x.UniqueData.Equals(y.UniqueData);
}
public int GetHashCode(TestAddable obj)
{
// since you are only comparing use `UniqueData` use that here for the hash code
return obj.UniqueData.GetHashCode();
}
}
Then to create the manager object do:
var additionManager = new AdditionManager<TestAddable>(new TestAddableComparer());
You can use a dictionary instead of a list. If you need a list in other parts of your code, it is easy to add a property that exposes the Values only.
public class AdditionManager<T> where T : IAddable
{
private Dictionary<int,T> addables;
public AdditionManager()
{
addables = new Dictionary<int,T>();
}
public void Add(T _addable)
{
if (!addables.ContainsKey(_addable.Data.RandomIntValue))
{
addables.Add(_addable.Data.RandomIntValue, _addable);
}
}
public Dictionary<int,T>.ValueCollection Values => _addables.Values;
}

Is there any better way to encapsulate an array?

How I do it currently:
class Foo
{
public int[] A { get { return (int[])a.Clone(); } }
private int[] a;
}
I think it's bad because it creates a clone and casts whenever I access it. I know I can work around it by introducing an additional variable like this
var foo = new Foo();
// as soon as you have to access foo.A do this
int[] fooA = foo.A;
// use fooA instead of foo.A from now on
but still it just looks bad.
I also dislike the java way of encapsulating
int get(int index) { return a[index]; }
because I dont get the advantages of using an array.
Is there any better way to do this?
edit: I want an array of encapsulated variables. The problem is that
public int[] A { get; private set; }
is not an array of encapsulated variables because I can modify elements of the array from outside of the class.
edit: It should also work with multidimensional arrays
Arrays implement IReadOnlyList<T> which exposes all of the relevant information you want (an iterator, an indexer, count, etc.) without exposing any of the mutable functionality of the array.
class Foo
{
public IReadOnlyList<int> A { get { return a; } }
private int[] a;
}
alternatively, you could use an iterator/generator to return the items as requested:
class Foo
{
public IEnumerable<int> A
{
get
{
foreach (int i in a)
yield return i;
}
}
private int[] a;
}
... then iterate over them normally or use LINQ to get them as a new array or other type of collection:
int[] arr = foo.A.ToArray();
Why not expose A as a implementation of IReadOnlyList
class Foo
{
public IReadOnlyList<int> A { get { return a; } }
private int[] a;
}
This allows you to return the Array as a collection where they can use the index but cannot change the contents of the array itself.
sounds like you need an indexer
...
public int this[int i]{
get{return a[i];}
set{a[i] = value;}
}
....
https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

How to create a method similar to ForEach

This is purely academic, but how would I create a method like the ForEach?
Say if I wanted to do something like the following:
SomeTenumerable.MyOwnFunction(x =>
{
x.Id = 0;
x.Order_Id = 0;
});
Note: I've only just got familiar with func<T,TResult>, so I'm not sure if it's the same thing.
Extra points if you can tell me the proper name/label of what I'm trying to achieve, I'm guessing it's some sort of delegate?
Demo here - https://dotnetfiddle.net/v7JKoo
.Each extension I use regularly - taken from http://extensionmethod.net/csharp/ienumerable-t/each-t
public static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
if (items == null) return;
foreach (var item in items)
action(item);
}
Example:
var items = new List<Item>();
// populate items
items.Each(item => item.DoSomething());
Yes you are passing in a delegate (here it is an Action) to perform on each item
PS if you are looking to return items look at linqs .Where or .Select
I think what you want to do is create an extension method (MSDN)
ForEach is a method in the List class (you can see the code here). Since you cannot add a method to the class, you can create an extension method that lives in your project but can be used as it was part of the original List class.
Let's say your items use this interface
public interface IYourInterface
{
int Id;
int Order_Id;
}
You create a static method in a static class:
static class HelperMethods
{
public static void ResetAll(this List<IYourInterface> collection)
{
collection.ForEach(x =>
{
x.Id = 0;
x.Order_Id = 0;
});
}
}
And then use the method on any instance of List.
var collection = new List<IYourInterface>();
collection.ResetAll();
var otherStuff = new List<string>();
// This won't work because because List<string> cannot
// be converted to List<IYourInterface>
// otherStuff.ResetAll();
Add Property class
Public MyClass
{
public static int Id {get;set;}
public static int Order_Id{get;set;}
}
You can set it like this
IEnumerable<MyClass> myclass = new IEnumerable<MyClass>(
{
Id = 0;
Order_Id = 0;
});
You can query through, serach throw etc.
See this question, Here The question itself not the anwer.

Using LINQ with wrapped arrays

I'm new to LINQ and I'm doing a simple project to learn the features of the technology.
Currently I've got a static class that wraps an array of object (a kind of simple factory). Let's say it looks like the following:
public static class Factory
{
private static Item[] items = new Item[]
{
// items are created here
};
// ...
}
Now I can add some functions to my Factory that allow me to query the inner array, e.g.
public static Item GetByID(ItemID id)
{
var query =
from item in items
where item.ID == id
select item;
return query.First();
}
However, this requires me to modify the internals of the Factory class. Is there a way to write such queries from the 'outer world' instead ?
public class OtherClass
{
var result = from it in Factory select ...
}
?
Yes, you can. Just use linq on the Factory from the 'outer world':
public class OtherClass
{
public Item Get(ItemId id)
{
return Factory.Items.SingleOrDefault(i => i.ID == id);
}
}
Of course, to do this, you'd need to change the access modifier of the items array to be public.
There are so many options.
The easiest thing to do is just to expose a public property that allows just what you want to have allowed:
public static class Factory
{
private static Item[] items = new Item[]
{
// items are created here
};
public static IEnumerable<IReadableItem> Items{ get { return items; } }
// ...
}
The above code assumes that the Item class implements an IReadableItem interface that only has the methods and properties on it that you want to allow people to access. You could also clone the items list before returning it each time, if you're worried someone might re-cast the Items or try to modify it using reflection. Because the standard LINQ methods all work off of IEnumerable<>s, this would allow someone to effectively produce a LINQ query on your items, without exposing overmuch data.
List<string> bestItemNames = Factory.Items.Where(i => i.IsBest)
.Select(i => i.Name)
.ToList();
If you wanted to get really fancy, you could even implement your own LINQ provider. From a language perspective, LINQ expression syntax just maps to specific method names, so if you had a class that implemented a .Where() and a .Select() method, then you could implement that pretty much however you wanted, and people wouldn't know any different until they tried doing something that your methods didn't support.
One possibility is to implement IQueryable<T> for a non-static class:
public class Factory<T> : IQueryable<T>
{
protected T[] _items = new T[]{};
public Type ElementType
{
// or typeof(T)
get { return _items.AsQueryable().ElementType; }
}
public System.Linq.Expressions.Expression Expression
{
get { return _items.AsQueryable().Expression; }
}
public IQueryProvider Provider
{
get { return _items.AsQueryable().Provider; }
}
public IEnumerator<T> GetEnumerator()
{
return ( IEnumerator<T> )_items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _items.GetEnumerator();
}
}
Derive non-generic class to populate array (if desired)
public class ItemFactory : Factory<Item>
{
public ItemFactory()
{
// items are created here
}
}
Create static instance
public static class Factories
{
private static ItemFactory _itemFactory = new ItemFactory();
public static ItemFactory ItemFactory { get { return _itemFactory; } }
}
Usage:
var specificItem = Factories.ItemFactory
.Where( item => item.ID == id )
.SingleOrDefault();
use an expression tree
public class OtherClass
{
public Item Get(ItemId id)
{
return Factory.Get(i => i.id == id);
}
}
and change the get method to
public Item Get(Expression<Func<Item,bool>> filter)
{
return items.SingleOrDefault(filter);
}
however, this approach makes little sense unless you are encapsulating some other logic in your factory class i.e. select only rows that are not soft deleted.

Clone object without changing the values of the original object C#

I need to make a copy of a MyGame class and use it in my simulation for game trials before I select a move to play.
For example :
public class MyGame
{
private int Start;
private Board board;
//Constructor
public void Play()
{
//play game
}
public object Clone()
{
}
}
public class Board
{
private int Count;
//Constructor
//Some methods and properties
public object Clone()
{
}
}
Writing code for the method Clone() I have tried
MemberwiseClone()
(Board) this.MemberwiseClone()
Board b = (Board) this.Board
I have read alot of articles and forums about this topic. The answer most people
use is Deep cloning objects in C#, I tried samples with respect to my project but I still
get my simulation modifying the original object (MyGame Class) and not the copy.
Here I have an example for a deep copy, which deeply copies all reference type objects that are used with a copy constructor:
public sealed class MyGame
{
private int start;
private Board board;
public MyGame(MyGame orig)
{
// value types - like integers - can easily be
// reused
this.start = orig.start;
// reference types must be clones seperately, you
// must not use orig.board directly here
this.board = new Board(orig.board);
}
}
public sealed class Board
{
private int count;
public Board(Board orig)
{
// here we have a value type again
this.count = orig.count;
// here we have no reference types. if we did
// we'd have to clone them too, as above
}
}
I think your copy might be somehow shallow and re-use some references (like for instance this.board = orig.board instead of creating a new board). This is a guess though, as I can't see your cloning implementation.
Furthermore, I used copy constructors instead of implementing ICloneable. The implementation is almost the same. One advantage though is that you simplify dealing with subclasses:
Suppose you had a MyAwesomeGame : MyGame, not overriding MyGame.Clone. What would you get from myAwesomeGame.Clone()? Actually, still a new MyGame because MyGame.Clone is the method in charge. One may carelessly expect a properly cloned MyAwesomeGame here, however. new MyGame(myAwesomeGame) still copies somehow incompletely, but it's more obvious. In my example I made the classes sealed to avoid this failures. If you can seal them, there's good change it will make your life simpler.
Implementing ICloneable is not recommended in general, see Why should I implement ICloneable in c#? for more detailed and general information.
Here I have an ICloneable approach anyway, to make things complete and enable you to compare and contrast:
public class MyGame : ICloneable
{
private int start;
private Board board;
public object Clone()
{
var copy = new MyGame();
copy.start = this.start;
copy.board = (Board)this.board.Clone();
return copy;
}
}
public class Board : ICloneable
{
private int count;
public object Clone()
{
var copy = new Board();
copy.count = this.count;
return copy;
}
}
The simplest and most reliable way to implement deep cloning is to serialize, and then deserialize your objects. This can have a large performance cost associated with it. Consider classes from this namespace for serialization http://msdn.microsoft.com/en-us/library/System.Xml.Serialization.aspx
Deep cloning requires recursively creating a new instance of every property that is not a value type. Cloning MyGame would require a new instance of MyGame and a new instance of Board, both populated with the same Start and Count values as their originals. This is fiddly and a nightmare to maintain. As you can guess, it is not an automatic process out of the box but it can be, using reflection (which is how the xml serialization above works.
MemberwiseClone only creates a new instance of the object you called it on - all references remain the same.
MemberwiseClone() creates a stupid shallow clone of each member of an object. This works fine when members are value types but in case of reference types it fails because it'll clone pointers and not pointed objects.
Starting from your code a memberwise clone is something like this:
public object Clone()
{
MyGame cloned = new MyGame();
cloned.Start = this.Start; // Copied (cloned) because value type
cloned.Board = this.Board; // This is not a copy, just a reference!
}
A better solution for a deep clone would be to implement ICloneable (for example, otherwise a copy constructor approach is also good) for each reference type, let's suppose Board is cloneable too:
public object Clone()
{
MyGame cloned = new MyGame();
cloned.Start = this.Start;
cloned.Board = (Board)this.Board.Clone();
}
Please note that in your example Board can implement Clone() using MemberwiseClone() because its members are all value types.
If you can't manage this (for example because code is not accesible) or you need a quick/dirty solution you may consider to user serializaiton (in memory). Which serializer is a big question, each one has some limitations (about what's serialized and how). For example XML serializer won't serialize private fields (it won't serialize fields at all). Faster one is binary formatter but you need to mark each class with a proper attribute.
Change according serializer you prefer (according to your requirements), in this case I assume you marked MyGame and Board as [Serializable] for the quick binary serialization:
public object Clone()
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(stream);
}
}
Try this
public static T DeepCopy<T>(this T obj)
{
T result;
var serializer = new DataContractSerializer(typeof(T));
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
ms.Position = 0;
result = (T)serializer.ReadObject(ms);
ms.Close();
}
return result;
}
I have two extension methods that I use to achieve this. Demo code below:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace SimpleCloneDemo
{
public class Program
{
public static void Main(string[] args)
{
var person = new Person { Id = 1, FirstName = "John", Surname = "Doe" };
var clone = person.Clone();
clone.Id = 5;
clone.FirstName = "Jane";
Console.WriteLine(#"person: {0}", person);
Console.WriteLine(#"clone: {0}", clone);
if (Debugger.IsAttached)
Console.ReadLine();
}
}
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public override string ToString()
{
return string.Format("Id: {0}, Full Name: {1}, {2}", Id, Surname, FirstName);
}
}
public static class ObjectExtensions
{
public static T Clone<T>(this T entity) where T : class
{
var clone = Activator.CreateInstance(entity.GetType());
var entityPropValueDictionary = entity.AsPropValueDictionary();
foreach (var prop in clone.GetType().GetProperties())
{
clone.GetType().GetProperty(prop.Name).SetValue(clone, entityPropValueDictionary[prop.Name]);
}
return clone as T;
}
public static IDictionary<string, object> AsPropValueDictionary<T>(this T instance, params BindingFlags[] bindingFlags)
{
var runtimeBindingFlags = BindingFlags.Default;
switch (bindingFlags.Count())
{
case 0:
runtimeBindingFlags = BindingFlags.Default;
break;
case 1:
runtimeBindingFlags = bindingFlags[0];
break;
default:
runtimeBindingFlags = bindingFlags.Aggregate(runtimeBindingFlags, (current, bindingFlag) => current | bindingFlag);
break;
}
return runtimeBindingFlags == BindingFlags.Default
? instance.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(instance))
: instance.GetType().GetProperties(runtimeBindingFlags).ToDictionary(prop => prop.Name, prop => prop.GetValue(instance));
}
}
}
Result:
I wrote these quick-and-dirty extension methods in a hurry so there are probably some issues with it and they are probably horribly inefficient, but they seemed to work for my use case. They may help you, too.

Categories