Initialize Lazy<T> with a known Value - c#

Question (TL;DR) in this constructor:
internal AnimalCollection(IReadOnlyList<Animal> animals, AnimalFlags aggregatedFlags)
{
AnimalList = animals;
_lazyAggregatedFlags = new Lazy<AnimalFlags>(() => aggregatedFlags);
var temp = _lazyAggregatedFlags.Value; // <<< ensure IsValueCreated == true
}
How can I avoid the overhead of initializing a brand new instance of Lazy just to immediately evaluate it, causing it to tear down most of the internal structures it just created, similar to Task.FromResult(...) when using tasks?
Context and further details:
Suppose I have an object representing a collection of animals (this is a re-mapping of my actual code to something question-friendly, so apologies that the structure is a bit odd for describing animals...).
[Flags]
enum AnimalFlags
{
Carnivorous = 1,
Prey = 2,
// etc.
}
public abstract class Animal
{
internal abstract AnimalFlags Flags { get; }
public bool IsCarnivorous => (Flags & AnimalFlags.Carnivorous) != 0;
// etc.
}
public class AnimalCollection
{
internal AnimalCollection(IReadOnlyList<Animal> animals)
{
AnimalList = animals;
}
public IReadOnlyList<Animal> AnimalList { get; }
}
public static class AnimalHelper
{
// Caller is expected to provide a known and immutable list of animals (not merely read-only)
// This simply wraps it up as an AnimalCollection.
static AnimalCollection GetAnimalCollection(IReadOnlyList<Animal> animals) => new AnimalCollection(animals);
// Caller supplies animals, we create an animal collection from them and must enumerate all animals in the process.
static AnimalCollection CreateAnimalCollection(IEnumerable<Animal> animals)
{
return GetAnimalCollection(animals.ToList());
}
}
GetAnimalCollection is used extensively in existing code. There are very large collections of existing animals, where we want to pre-populate an animal collection using one. Also assume some other classes implementing IReadOnlyList that allow subsets to be selected without enumerating the whole list, etc.
Rather than enumerating all animals in the collection that allows callers to completely skip the collection if it doesn't contain any carnivorous animals, I'd like to add a property to the AnimalCollection. A naive implementations could add a simple property like:
public bool IsAnyCarnivorous => AnimalList.Any(a => a.IsCarnivorous);
But it makes more sense to aggregate the flags once, using Lazy, for example:
public class AnimalCollection
{
internal AnimalCollection(IReadOnlyList<Animal> animals)
{
AnimalList = animals;
_lazyAggregatedFlags = new Lazy<AnimalFlags>(() => AnimalList.Aggregate(default(AnimalFlags), (flags, animal) => flags | animal.Flags));
}
Lazy<AnimalFlags> _lazyAggregatedFlags;
public bool IsAnyCarnivorous => (_lazyAggregatedFlags.Value & AnimalFlags.Carnivorous) != 0;
public IReadOnlyList<Animal> AnimalList { get; }
}
However, when using CreateAnimalList, we now enumerate the list twice - once to create the list, and again to get the aggregated flags. That's a little inefficient, so we can change the ToList() shortcut to build the list ourselves and get the aggregated flags at the same time:
static AnimalCollection CreateAnimalCollection(IEnumerable<Animal> animals)
{
var animalsList = new List<Animal>((animals as ICollection)?.Count ?? (animals as IReadOnlyList<Animal>)?.Count ?? 0);
AnimalFlags aggregatedFlags = 0;
foreach(var animal in animals)
{
animalsList.Add(animal);
aggregatedFlags |= animal.Flags;
}
return GetAnimalCollection(animalsList, aggregatedFlags);
}
Adding a new constructor to AnimalCollection:
internal AnimalCollection(IReadOnlyList<Animal> animals, AnimalFlags aggregatedFlags)
{
AnimalList = animals;
_lazyAggregatedFlags = new Lazy<AnimalFlags>(() => aggregatedFlags);
var temp = _lazyAggregatedFlags.Value; // <<< ensure IsValueCreated == true
}
This constructor could also be used in other contexts, such as when combining collections of animals (and therefore combining their aggregated flags), which can then be very quick operations.
However, it seems to have made a bit more work for itself than necessary.
If, instead of Lazy<T>, I'd been using a Task<T>, I would be able to use Task.FromResult(aggregatedFlags) to avoid the additional overhead of creating a complex object to contain an already-known value. I can't see an equivalent way to instantiate a Lazy<T> from a known value already in hand. Am I missing something?

Best answer I came up with myself after the initial discussion, from reviewing a little more documentation and the reference source is to add LazyThreadSafetyMode.None, which avoids a tiny amount of overhead from acquiring a lock.
internal AnimalCollection(IReadOnlyList<Animal> animals, AnimalFlags aggregatedFlags)
{
AnimalList = animals;
_lazyAggregatedFlags = new Lazy<AnimalFlags>(() => aggregatedFlags, System.Threading.LazyThreadSafetyMode.None);
var temp = _lazyAggregatedFlags.Value; // <<< ensure value created on this thread before returning
}
This can be wrapped in a helper method:
public static class LazyHelper
{
public static Lazy<T> FromValue<T>(T value)
{
var result = new Lazy<T>(() => value, System.Threading.LazyThreadSafetyMode.None);
var tmp = result.Value; // <<< ensure value created on this thread before returning
return result;
}
}
... simplifying the constructor to:
internal AnimalCollection(IReadOnlyList<Animal> animals, AnimalFlags aggregatedFlags)
{
AnimalList = animals;
_lazyAggregatedFlags = LazyHelper.FromValue(aggregatedFlags);
}
The overhead of wrapping a value in a Lazy<T> is orders of magnitude less than the overhead involved in Task.Run(() => value), which perhaps explains why the latter has a pre-existing Task.FromResult(value). #Corak mentioned in chat that if you're working with .Net Core, [Lazy<T> has] a constructor that takes the T directly. This seems to me a syntax that would be likely to give confusion given other questions I've seen about Lazy<T> (e.g. someone may call the non-lazy constructor expecting it to work lazily)
In any case, absent anything obvious I've overlooked, I don't need to continue with nano-optimisations.

Related

Can I store a list of types and access their static properties through an interface?

Let's say I have an interface ICar:
public interface ICar
{
static int WheelSize { get; }
}
And I have two classes that implement the interface:
class FirstCar: ICar
{
static int WheelSize { get; } = 28;
}
class SecondCar : ICar
{
static int WheelSize { get; } = 24;
}
I would like to store these types in a list, and retrieve their static properties without having to call GetProperty("propName")Value(Null) on the type object:
List<Type> cars = new List<Type>();
cars.Add(typeof(FirstCar));
cars.Add(typeof(SecondCar));
foreach (Type car in cars)
{
// I want to do something like this:
int size = ICar<car>.WheelSize;
// But I currently have to do this:
size = (int)car.GetProperty("WheelSize").GetValue(null);
// or this:
size = (int)car.GetProperty(nameof(ICar.WheelSize)).GetValue(null);
}
Is there any way to store a list of types that implement a known interface, and access their static properties in a strongly-typed manner?
I would (maybe naively) love to store a list of generics directly rather than having to create type objects, but I don't think that's even remotely possible?
To give further information about the problem that I would like to solve:
I would like to display a dropdown box that shows the types of cars that you can create (so in this example, a list that contains a FirstCar type and a SecondCar type). I would like to display their respective WheelSizes without needing to create instances of each (the properties are static so why should I need to create instances?). As a result, I store a list of the types that can be created, rather than instances of the objects. Unfortunately the only way I can then access the WheelSize property from the Type object, is by using a string to retrieve the value based on the property name, which doesn't feel right.
Follow Up:
As pointed out by Guru Stron , I can change the interface property to a string and it still compiles. The class properties are therefore not the same as the interface property, and as a result, I cannot expect to be able to resolve them through the interface. I cant say I understand why they are not the same, but the fact that they aren't must be the (or a) reason why I can't do what I want.
You can do something like this:
var dict = new[] { typeof(FirstCar), typeof(SecondCar) }
.Select(t => new
{
Type = t,
Func = (Func<int>) t.GetProperty("WheelSize", BindingFlags.NonPublic | BindingFlags.Static).GetMethod.CreateDelegate(typeof(Func<int>))
})
.ToDictionary(d => d.Type, d => d.Func);
Console.WriteLine(dict[typeof(FirstCar)]()); //28

Creating a list composed of object property references

I am trying to do the following thing:
- From within a 1st method, I am going through a bunch of objects (of same type) and extracting pointers to specific properties into a list
- This list will then be fed to a another method elsewhere in my program at some point in time and has to modify all the properties (as per provided list) of the original objects
In other words, say we have the following class:
public class Something
{
public SomeFlag = False;
public Something()
{
}
}
Somewhere in the system, we have composed a related list of objects into List.
Now, we want to scan through this list and extract into "List< bool> flags" all the flags (by reference?):
List<bool> flags = new List<bool>();
foreach (var stuff in List<Something>)
{
flags.Add(stuff.SomeFlag);
}
Finally, somewhere else, I want to update these flags, but the update should affect the original object:
public static void SetStates(List<bool> myList)
{
// The flag should get set to true by reference in the original object
myList.SomeFlag = True;
}
Using actions could be one way to achive this:
public class Something
{
public bool SomeFlag { get; set; }
}
internal class Program
{
private static void Main()
{
var somethings = new[] {new Something(), new Something()};
var flags = new List<Action<bool>>();
// create your list of 'pointers'
foreach (var something in somethings)
{
flags.Add(x => something.SomeFlag = x);
}
// set them all to true
foreach (var action in flags)
{
action(true);
}
// check the results
foreach (var something in somethings)
{
Console.WriteLine(something.SomeFlag);
}
Console.WriteLine("press any key to exit...");
Console.ReadLine();
}
}
In C#, you cannot save a reference to a property value (like a pointer to the memory location where the value is stored). You only can save a reference to an object which contains this property value.
In your var list = new List<Something>(), you can store those references to the objects.
Note that it's impossible for value types though. If Something is a struct, not a class, then the list will contain copies of the objects, not the references to the objects. So the rest of my answer assumes we're talking about class Something.
You can define a property changing behavior and apply it using the list of the objects.
If you already know at compile time which properties and which values do you need, you can create a lambda and pass it around.
// Define the behavior and get the object list
Action<Something> setter = o => o.Someflag = true;
var objectList = new List<Something>();
// Call your processing method later on
SetProperties(objectList, setter);
void SetProperties<T>(List<T> objects, Action<T> setter)
{
objects.ForEach(setter);
}
If you don't know at compile which properties and which values you will need, then things get much more complicated. You will need to use Reflection to obtain the property descriptors and to set the values.
Here is a simplified example:
// Define the behavior and get the object list
var objectList = new List<Something>();
string propertyName = "SomeFlag";
PropertyInfo pi = typeof(Something).GetProperty(propertyName);
MethodInfo setter = pi.GetSetMethod();
object value = true;
// Call your processing method later on
SetProperties(objectList, setter, value);
void SetProperties<T>(List<T> objects, MethodInfo setter, object value)
{
var arguments = new object[] { value } ;
objects.ForEach(o => setter.Invoke(o, arguments));
}

Perform a 'task' via an enum and a field, by checking the 'T' type, and inferring it into the task automatically

I've come across an issue that I cannot solve. I've got an IReadOnlyList of classes that each have a bunch of fields. These fields have names (variable names) identical to a list of enums. Think that for each field that exists, an enum for it with the exact same name also exists (so object helloHi has an equivalent enum something { helloHi }).
What I've attempted to do is compare the two field names. If they are identical, perform a function on them. The problem is that the function needs to infer a T from the variable, and since reflection isn't able to pull that 'T' without some form of cast, it won't proceed.
This is the code:
public class Something() {
[BackgroundTask]
private void load(Overlay param_1, Config param_2) {
Children = new Drawable[] // is the IReadOnlyList
{
SomethingClass(param_1),
AnotherClass(param_2)
}
performTask(this, param_2);
}
}
public class Config {
public void task<U>(SomeEnums se, ValueType<U> value) // do the task
}
public class SomethingClass {
ValueType<double> someDouble = new ValueType<double>();
ValueType<int> someInt = new ValueType<int>();
public SomethingClass(Overlay overlay) //...
}
public enum SomeEnums {
someDouble,
someInt,
}
void performTask(Something the_class, Config the_config) {
// ... for each field within the_class, do (uses reflection)
field => {
foreach (SomeEnums enums in Enum.GetValues(typeof(SomeEnums)))
{
if (field.Name == enums.ToString()) {
the_config.task(enums, field.GetValue(null)); // cant infer 'U' from an 'object'
}
}
}
}
Technically, I could just do the config.task within the class where the types are known and visible, but I'd much prefer to automate it from here, so that it doesn't need 2-3 changes every time a new variable is created.
One of the strategies I am aware of is performing an if check within the performTask like such:
// performTask, field =>, foreach
{
if (field.FieldType == ValueType<double>)
config.task(enums, (ValueType<double>)field.GetValue(null));
} //etc
However, I don't like this method. It would just need to introduce more and more checks if I ever created more ValueType<> and if they aren't already being checked for. Would there be a better way to perform what I want?
As I mentioned in my comment, I can't quite tell what you really want to do. However, here's some code that should help you figure it out.
It uses reflection to get the fields of objects, look at the names of those fields (comparing them to the values/names associated with an enum type) and compare the values. I do a comparison to integer 5, but you could compare to anything (but, it appears that the integer type's implementation of IComparable.CompareTo throws if it's compared to something other than an int, so I check). Since you know the type of everything, this is easy to check (you don't have to compare to a fixed Type, you can use what is returned by GetType()).
I started with some auxiliary types:
public enum SomeEnums {
SomeDouble,
SomeInt,
}
public class Class1 {
public int SomeInt = 5;
public double SomeDouble = 3.14;
}
public class Class2 {
public int SomeInt = 5;
public double SomeDouble = 6.28;
}
and then added this:
public class EnumFields {
public List<object> Objects = new List<object> {
new Class1(),
new Class2(),
};
public void PerformTask () {
var enumVals = Enum.GetNames(typeof(SomeEnums));
foreach (var obj in Objects) {
var objType = obj.GetType();
var fieldInfos = objType.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
//right around here I get lost. You have a list of objects (which has two instances right now),
//What are you comparing, that every field named SomeInt has the same value??
//Anyway, here's some code that should help you
foreach (var fieldInfo in fieldInfos) {
if (enumVals.Contains(fieldInfo.Name)) {
var fieldObj = fieldInfo.GetValue(obj);
var isSame = false;
if (fieldObj.GetType() == typeof(int)) {
var comparable = (IComparable)fieldObj;
var same = comparable.CompareTo(5);
isSame = (same == 0);
}
Debug.WriteLine($"Field: {fieldInfo.Name} of instance of {obj.GetType().Name} (Value: {fieldObj}) is equal to 5:{isSame}");
}
}
}
}
}
When I instantiate an EnumFields object and call PerformTask on it, I see this in the output:
Field: SomeInt of instance of Class1 (Value: 5) is equal to 5:True
Field: SomeDouble of instance of Class1 (Value: 3.14) is equal to 5:False
Field: SomeInt of instance of Class2 (Value: 5) is equal to 5:True
Field: SomeDouble of instance of Class2 (Value: 6.28) is equal to 5:False
This should get you most of the way there. I realize it doesn't answer your question. Had I been able to figure out what you were asking, it probably would have.

Order readonly List

I have a readonly List so I can hide the Add method from other classes, like this:
class Foo
{
private readonly List<Bar> _Bars = new List<Bar>;
public()
{
this.Bars = _Bars.AsReadOnly();
}
public ReadOnlyCollection<Bar> Bars
{
get;
private set;
}
public void AddBar(Vector Dimensions)
{
_Bars.Add(new Bar(Dimensions));
}
}
The thing is, now I want to order the _Bars field of an instance of Foo, like such:
public void OrderBarsByVolume()
{
_Bars.OrderByDescending(o => o.Volume); //Doesn't do anything
_Bars = _Bars.OrderByDescending(o => o.Volume).ToList(); //Error: A readonly field cannot be assigned to
}
Is it possible to use orderby and keep the add feature of the List hidden from other classes?
Use List<T>.Sort method
_Bars.Sort((x,y) => x.Volume.CompareTo(y.Volume));
Not with your current implementation, however, if you adjust things slightly then yes you can. The idea of "hiding" the underlying data means you don't have to hold it internally as read only but rather expose it as read only
private List<Bar> _Bars = new List<Bar>();
public ReadOnlyCollection<Bar> Bars
{
get { return _Bars.AsReadOnly(); }
}
public void OrderBy(Func<Bar, bool> src)
{
_Bars = _Bars.OrderByDescending(src);
}
...
var foo = new Foo();
foo.OrderBy(x => x.Volume);
If you feel creating a new ReadOnlyCollection each time is too expensive then keep your code as it is but simply remove the readonly modifier
private List<Bar> _Bars = new List<Bar>;
public void OrderBy(Func<Bar, bool> src)
{
_Bars = _Bars.OrderByDescending(src).ToList();
}
Add a public method that will do the ordering within the Foo object.
Even if James gave you some good tips, there are still some open issues.
So let's start with your implementation:
private readonly List<Bar> _Bars = new List<Bar>;
This won't make the list itself read-only. Still it is possible to add, remove an item or to clear the entire list. The keyword readonly only ensure that you can't replace the whole list by a completely different list.
So what you like, is that within your class you have full access to the list (so Foo can add, remove, sort items), but anybody who requested the list, can only read this list. The open question here would be what should happen if someone requested the list and afterwards the list was changed from Foo. Should the already outgiven list reflect theses changes or not? Mostly you like this behaviour, but it really depends on what you like to achieve.
Here is my code example that should solve most of your problems:
internal class Foo
{
// The list which can be manipulated only be Foo itself.
private List<Bar> _Bars;
// The proxy that will be given out to the consumers.
private ReadOnlyCollection<Bar> _BarsReadOnly;
public Foo()
{
// Create the mutable list.
_Bars = new List<Bar>();
// This is a wrapper class that holds a
// reference to the mutable class, but
// throws an exception to all change methods.
_BarsReadOnly = _Bars.AsReadOnly();
}
public IReadOnlyList<Bar> Bars
{
// Simply give out the wrapper.
get { return _BarsReadOnly; }
}
public void AddBar(Vector dimensions)
{
// Manipulate the only intern available
// changeable list...
_Bars.Add(new Bar(dimensions));
}
public void SortBars()
{
// To change the order of the list itself
// call the Sort() method of list with
// a comparer that is able to sort the list
// as you like.
_Bars.Sort(BarComparer.Default);
// The method OrderBy() won't have any
// immediate effect.
var orderedList = _Bars.OrderBy(i => i.Volume);
// That's because it will just create an enumerable
// which will iterate over your given list in
// the desired order, but it won't change the
// list itself and so also not the outgiven wrappers!
}
}
To use the Sort() method of the list class you need an comparer but that's quite easy to implement:
internal class BarComparer : IComparer<Bar>
{
public static BarComparer Default = new BarComparer();
public int Compare(Bar x, Bar y)
{
if (ReferenceEquals(x, y))
return 0;
if (ReferenceEquals(x, null))
return -1;
if (ReferenceEquals(y, null))
return 1;
return x.Volume.CompareTo(y.Volume);
}
}
I hope this gives you a little more enlightenment about how stuff in C# works.
Let the callers handle the sorted list:
public IEnumerable<Bars> OrderedBars(Func<Bar, bool> sortMethod)
{
return _Bars.OrderBy(sortMethod);
}
If you really want to keep the sorted bars to yourself, you could create a immutable class where ordering the bars create a new instance of Foo which will then either replace the current one or be used by the caller, something like that:
public Foo OrderBarsByVolume()
{
return new Foo() {_Bars = this._Bars.OrderByDescending(o => o.Volume)}
}

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