It is both easier and harder than you might imagine.
What you are referring to, duplicating a memory block, is only a shallow clone.
If an object has references to other object, those other objects also need to be duplicated for the object to be cloned properly.
A deep clone is possible to do automatically, but is very slow (activating a new instance, reflecting and iterating over all fields of the type and recursively cloning any nested objects)
If all you want is to say, be able to copy a small collection of value types, define your type as a 'struct' instead of a 'class', and you will get the ability to easily create clones of an object. Types defined as a 'struct' inherit from 'ValueType', and are passed by value (eg, a duplicate) to functions, or when assigned to fields. Builtin types such as 'int', 'float', 'double' and the like are all value-types, and you can expect your own value-types to behave the same way. If you need 'null' as a value, you must use Nullables (eg, use 'int?' instead of 'int' to allow null to be a possible value)
With a struct/value type, creating a shallow is as easy as assigning some other field/variable to the value you want to copy. Creating a deep copy (unless the type is composed of only value types) still has the same problems as described above.