December 23, 2016

Invoking a delegate from inside a dynamic method

As always, one question at StackOverflow attracted my attention and made me program all the night. The question was actually about a way to refer to a predefined object in a dynamically emitted method in a dynamic assembly. That is actually quite an easy task, provided you aren't going to save the assembly and use it later in a different program. In this case, simply use some way to refer to the object using a number (add it to a list, or use a GCHandle) and there's nothing easier than emitting an integer in CIL.

If you want to save the assembly, this approach obviously will not work, as the object will be lost when you quit the runtime. In this case, you'd have to find an optimal way to serialize the desired object, either directly calling its constructor in method, or use a serializer and put the result in the assembly resource space.

However, for some strange reason, I didn't immediately think about those two ways, probably because it was late night. Instead, I thought about compiled lambdas in Linq.Expressions and how closures work there (mainly Expression.Constant). Behind all that emitting, it's actually quite simple - if you know how delegates work. Someone coming over from the land of C will think about delegates as wrappers for function pointers, but it's more than that. You can bind a function pointer to a specific target object, which is then internally used as the first argument to the method (you can actually even bind static methods to target objects, and they behave as expected).

LINQ Expressions work the same way - the compiled lambda is dynamically emitted, and non-primitive constants are placed in a special container, which is then used as the target object of the created delegate. The compiled method would then access the container as easily as using this in an instance method. Provided I wouldn't have to save the assembly, what if I were to bind the desired object to a delegate and then call that delegate in the dynamic assembly?

The immediate problem here is obvious - the delegate has a target object, and I still have no way (ignore the first paragraph) to refer to it from inside the dynamic method. What I would want is a way to generate a piece of code that somehow stores the delegate and its target object, and would allow me to call it as a raw function pointer. Hmm, is there something in .NET that does that?

Connecting emitting and interop

Actually, I recalled there is - Marshal.GetFunctionPointerForDelegate. A bit of an overkill, having to generate all that marshalling code for a method that is never intended to be called from an unmanaged code, but whatever, it works. And I get a function pointer from a delegate, without any additional data. However, it's an unmanaged function pointer, so I have to convert it back to a managed one. Naturally, the method has a counterpart - Marshal.GetDelegateForFunctionPointer, but unfortunatelly, it is too smart for me to use it. It traverses an internal hash table and checks it there's some delegate that has been already converted to an unmanaged function pointer, and finds the original one, returning it. I have to tell the method not to do that and simply generate a new thunk, but how...?

Marshal.GetManagedThunkForUnmanagedMethodPtr comes to my mind, me having seen that method often when browsing the Marshal class. It sounds like it should accomplish what I seek, although the naming seems strange at first (function pointer vs. method pointer). There is a "small" caveat, though. The arguments are "IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature", and MSDN does nothing helpful than retelling their names in plain English. The first argument should be obviously the unmanaged function pointer in question, but what about the rest? In C#, the signature of a method is basically the list of all its parameter types, but that's not what the method needs. I have to obtain the CIL signature of the metod.

Coming back to CIL

ECMA-335 is an excellent reading, if you want to know more about CIL and signatures. In short, it's a byte array containing information about the method's return type, parameter types, and the managed calling convention (like varargs). For a plain method without any return type or parameter types, the signature is "00 00 01". I am not going to describe it in detail; read the ECMA specification for that.

But how to actually obtain the correct signature of the method, other than generating it via using the specification and reflection? Pardon me for promoting my own library, but there are already means there to accomplish this. Using the ReflectionTools.GetSignature method, I have a quick way of obtaining the signature of a method (albeit in the context of its own module), so I simply get a pointer to the array, and the whole call is easy.

Action m = TestMethod; //The delegate I want to call
var sig = ReflectionTools.GetSignature(m.Method);

var ptr = Marshal.GetFunctionPointerForDelegate(m);

unsafe{
    fixed(byte* sigptr = sig)
    {
        var thunk = Marshal.GetManagedThunkForUnmanagedMethodPtr(ptr, (IntPtr)sigptr, sig.Length);
      
        var del = (Action)FormatterServices.GetUninitializedObject(typeof(Action));
        typeof(Delegate).GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(del, thunk);
        del();
    }



The second part of the code is a quick and ugly way of initializing a delegate directly from the method pointer. And guess what - it actually works. Although the resulting delegate can be only invoked and other actions produce an exception, it's not a problem, as I only wanted to see it it can be called by the function pointer. The only thing left is to see whether it is possible to emit a code that calls the function pointer:

public static Delegate WrapFunctionPointer(IntPtr fnPtr, MethodSignature signature)
{
    var dyn = new DynamicMethod("_FnPtrCall", signature.ReturnType, signature.ParameterTypes, typeof(Program).Module, true);
    var il = dyn.GetILGenerator();
    for(int i = 0; i < signature.ParameterTypes.Length; i++)
    {
        il.EmitLdarg(i);
    }
    if((ulong)fnPtr <= UInt32.MaxValue)
    {
        il.Emit(OpCodes.Ldc_I4, (uint)fnPtr);
    }else{
        il.Emit(OpCodes.Ldc_I8, (ulong)fnPtr);
    }
    il.Emit(OpCodes.Conv_I);
    il.EmitCalli(OpCodes.Calli, signature.CallingConvention, signature.ReturnType, signature.ParameterTypes, null/*signature.OptionalParameterTypes*/);
    il.Emit(OpCodes.Ret);
    var delType = ReflectionTools.GetDelegateType(signature.ReturnType, signature.ParameterTypes);
    return dyn.CreateDelegate(delType);
}


Ignore the MethodSignature type, it's just an another type in my library, and it simply stores information necessary to describe a method signature (types and calling convention). The calli opcode is the black magic that does the rest - it is the way to call a function pointer without having to specify the method, probably used heavily in C++/CLI code. ReflectionTools.GetDelegateType is another nice method from my library, but you can imagine typeof(Action)instead of it, in the context of a simple method.

So yes, it is possible to "bake" the target object in a delegate and then call it without specifying one, but having to step into unmanaged code in order to do it makes this way unfit for production code. What's nice though is that I have accurately recreated GetDelegateForFunctionPointer using GetManagedThunkForUnmanagedMethodPtr and WrapFunctionPointer and a bit of reflection hacks.

July 24, 2016

C++/CLI type system as seen from .NET and CIL

For some time now, I have delved, out of necessity, into C++ and all its quirks and secrets. One thing that has always fascinated me in C++ is its marvelously complex type system. In C#, you can mostly just work with arrays, pointers are possible but not recommended, and also generics. C++ has loads of declarators – arrays with fixed size, pointers, references, and this all can be combined with anything else and also qualifiers – mostly const and volatile. These two keywords also exist in C#, but they have vastly different meaning.

Now you may be surprised or not, but all these constructions are actually accurately representable in Common Intermediate Language (CIL for short), the language that separates all .NET languages from native code. Though C# doesn't show the full potential of its type system (however, the newest drafts have quite appealing suggestions, like ref returns), in CIL, the type system is as rich as C++'s, maybe even richer.

C++/CLI is a beautiful and well-designed combination of C++ and .NET, and shall serve as an example of how its types are translated into CIL. If you are not familiar with C++ at all, don't worry, I'll be easy on you. The following descriptions will be mainly from the C# perspective; all in all, that's from whence I come.

Let's start with an overview of what types we'll have to consider:

Managed classes

 

.NET classes are probably what you all already know. In C#, they are defined with "class Name". They are reference types, meaning their actual data is always stored on the heap, and is only refered to via an opaque value (called reference, internally a pointer to an object). C++/CLI defines them with "ref class Name" or "ref struct Name". Be aware that class and struct in C++ have totally different meaning than in C#. Class has all its members private by default, whilst struct has all members public by default. There's no other considerable difference between the two keywords in C++.


Managed structs

.NET value types can be located on the stack, and are usually used for simple values or aggregates of values. C# defines them with "struct Name". In C++/CLI, it's again either "value class Name" or "value struct Name".


Native types

 

User-defined native type is created in C++/CLI via "struct Name" or "class Name", again the difference being only in the default visibility of members. All native types are translated as value types in C++/CLI, because they have value semantics. Compiled native types have only their size specified in the CIL assembly, and all their methods are located in the global module type.

In the current version of C++/CLI, "mixed" types aren't supported. You cannot have a managed type containing a native type member, or vice versa. However, managed methods can take, return, and have locals of native types. The problem in mixed types are so-called "interior pointers". They point to the inside of an object, and objects on managed heap are frequently moved around the heap by the GC (garbage collector). In this case, a function expecting a pointer to a value (possibly as this) would result in the location being moved in the middle of the function. There are plans to unify the type system, but nothing so far released.

Now as I have listed the basic types, let's look at how the compiler translates some more compilated ones.


No declarators

 

A native type without any declarators:

static std::exception TestFunc()

translates into the following line in CIL (got via ildasm):

.method private hidebysig static valuetype std.exception* modreq([mscorlib]System.Runtime.CompilerServices.IsUdtReturn)
        TestFunc(valuetype std.exception* A_0) cil managed


For those yet unfamiliar with CIL, .method starts a method definition, private is the same as in C# and hidebysig specifies hiding members of base class. After "static" comes the return type:

valuetype std.exception* modreq([mscorlib]System.Runtime.CompilerServices.IsUdtReturn)

Yes, that's the whole return type. See what I meant with rich type system? Anyway, valuetype std.exception is a type reference to the user-defined class (as I said, all native types are value types), * is a good old pointer to it, and now comes the fun. A "feature" completely missing in C# (at the moment, it might be in C# 7 or future) are optional and required modifiers. You see, a custom attribute is a piece of metadata represented with a specific type, attached to a method, field, parameter etc. A modifier is a type attached to another type. That's the most important aspect of modifiers. An optional modifier (modopt) can, by definion, be ignored safely by any compiler that doesn't understand it without any risks. On the other hand, a required modifier (modreq) has to be understood by the compiler in order to use the type correctly. I assume that the C# compiler isn't aware of the modifier, and therefore shouldn't allow for the access to this method.

MSDN explains the modifying type IsUdtReturn quite well:
The IsUdtReturn modifier is used by the C++ compiler to mark return types of methods that have native C++ object return semantics. The managed debugger recognizes this modifier to correctly determine that the native calling convention is in use.

Another quite interesting thing about this method is the single parameter. I am not much into the internals of C++, but it seems from the method body that the actual type is initialized or copied right into the variable accessed by the pointer. It is not surprising much, though, given that you can even overload the assignment operator in C++, and it is also possibly faster this way.

For comparison, let's see how a method looks if it returns a managed struct:

.method private hidebysig static valuetype [mscorlib]System.DateTime
        TestFunc() cil managed


As you can see, there is no difference between C# and C++/CLI output in this case, which is actually no surprise given it has to be compatible.

I used struct, but what about a regular class? C++/CLI can actually support value type semantics for reference types, so how would it look with a managed reference type?

.method private hidebysig static void modreq([mscorlib]System.Runtime.CompilerServices.IsUdtReturn)
        TestFunc(class [mscorlib]System.Exception& A_0) cil managed


It looks quite similar to the first method but this time the return type is void. It seems logical, because a pointer to a managed reference type is not valid. The parameter is also analogous to the first method, but it's a reference (ref in C#, & in CIL) this time (again because a pointer would be invalid).

As you can see, using bare managed reference type as a return type is not a good example, so we'll try just parameters further on (there is little to no difference in case of the other types with declarators).

class [mscorlib]System.Exception modreq([mscorlib]System.Runtime.CompilerServices.IsByValue)

There is simply no way a reference type instance could be located on a stack in .NET, and the value behaviour is just simulated in C++/CLI. CLR still sees just a reference being passed to the method.

MSDN on IsByValue:
The IsByValue class is used by the Microsoft C++ compiler to denote method parameters and return values whose semantics follow the C++ rules for objects passed by value


Pointers

 

There is nothing special to the translation of pointers:

valuetype std.exception*

valuetype [mscorlib]System.DateTime*


Both native and managed value types are translated without any special modifiers, being compatible with C#.


References

 

A reference in C++ is just a pointer under the hood, but it doesn't have to be dereferenced (the * operator) in order to access its value, because it is implicitly dereferenced.

valuetype std.exception* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced)

The same for managed value types. As you can see, it's modopt and not modreq this time, so C# should be able to use this method. There is no reason for it not to be able to.

MSDN on IsImplicitlyDereferenced will be quoted further below, because it doesn't describe the current usage context.

As reference is just a pointer, it also cannot be used for managed reference types.


Handles

 

A handle is what C# guys would call a reference to an instance. In C++/CLI, the syntax is System::Object^ and it can be used only for managed types.

object

That's what ildasm displays. It could also be [mscorlib]System.Object, but this one is shorter in the assembly code. As you can see, a handle to a managed reference type is simply the reference type itself in both CIL and C#. But what about a value type?

class [mscorlib]System.ValueType modopt([mscorlib]System.DateTime) modopt([mscorlib]System.Runtime.CompilerServices.IsBoxed)

A "handle" to a value type is simply a boxed value. CIL cannot represent this directly, but since all value types inherit from ValueType, it is the best type for it. It is also modified with the actual expected type (not enforced by CLR or C# if you pass a different type, though) and IsBoxed.


MSDN on IsBoxed:
Indicates that the modified reference type is a boxed value type. This class cannot be inherited.
The Microsoft C++ compiler supports boxed value types directly in the language. Information about boxed value types is emitted into metadata as a custom modifier, where the modifier decorates a reference to the value type being boxed.
There cannot be a handle to anything else. A handle to a pointer would be somewhat logical and possible, but only if pointers were able to be boxed, which they aren't (they are boxed to IntPtr, actually).


Tracking references

 

A tracking reference is a reference which the GC knows about, and moves its address accordingly. As you probably see now, it's a plain old ref in C#, albeit with a fancier name. The syntax in C++/CLI is System::DateTime%. They can be used with any other type, except with another reference (ECMA-335 for CLI explicitly states that a managed pointer [= ref] can point to unmanaged data without any problems, and the GC won't move it).

Native types and value types are translated the same:

valuetype [mscorlib]System.DateTime&

It is completely identical to ref DateTime in C#. It gets interesting for bare reference types (System::Object%), though:

object modreq([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced)

The parameter cannot be a reference, because that would be setting the instance reference, and not its data.

Now it's good time to quote the MSDN:
The C++ compiler uses the IsImplicitlyDereferenced modifier to distinguish reference classes that are passed by managed reference from those passed by managed pointer. The IsImplicitlyDereferenced class and its partner, the IsExplicitlyDereferenced class, disambiguate reference parameters from pointer parameters.
The description is a bit cryptic, but it shows the point. "managed reference" is a tracking reference, and "managed pointer" is a handle.


Arrays

 

In C++ an array is usually specified with a fixed size, but an "array of unknown bound" is also possible. If used as a field, it occupies the space of the object (like unsafe fixed arrays in C#) like a value type. If used as a parameter, it decays into a const pointer. As a local variable, it allocates space on the stack and also decays to a pointer.

static void TestFunc(int (&arr)[10])

There is no difference in the values being passed around, but this time, the array type is preserved in the method signature... mostly:

valuetype '<CppImplementationDetails>'.$ArrayType$$$BY09H* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced)

$ArrayType$$$BY09H is actually quite similar to mangled names for C++ functions. You can read the details here, but Y is an array prefix, 0 means 1 dimension, 9 is the size of the array (10 in fact, but encoded as 9, see the documentation), and H is signed int. typeid(int(&)[10]).raw_name() returns .$$BY09H. IsImplicitlyDereferenced is used again to distinguish a reference from a pointer.

The actual array type is just a value type with a custom size:

.class private sequential ansi sealed beforefieldinit '<CppImplementationDetails>'.$ArrayType$$$BY09H
       extends [mscorlib]System.ValueType
{
  .pack 0
  .size 40
  .custom instance void [Microsoft.VisualC]Microsoft.VisualC.DebugInfoInPDBAttribute::.ctor() = ( 01 00 00 00 )
  .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 )
  .custom instance void [mscorlib]System.Runtime.CompilerServices.NativeCppClassAttribute::.ctor() = ( 01 00 00 00 )
  .custom instance void [Microsoft.VisualC]Microsoft.VisualC.MiscellaneousBitsAttribute::.ctor(int32) = ( 01 00 41 00 00 00 00 00 )
}


The size is sizeof(int)*10, i.e. 40. I haven't been able to find what the last bits mean.

Managed arrays in C++/CLI have a nice little template-like syntax:

array<type, dimensions>^

In principle, .NET arrays can also have additionally specified index for their dimensions. No .NET language know to me (except CIL) can take advantage of this.


Const and volatile qualifiers

 

modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
modopt([mscorlib]System.Runtime.CompilerServices.IsVolatile)

Not a much surprise, after all those modifiers we have seen. The modifier follows the type it modifies, like in C++ (if it's not directly on the left).


Function pointers

 

Another lesser known feature of CIL, especially because of their poor handling in .NET reflection, are function pointers. Normally, you would use a delegate if you wanted to capture a method into an object. However, there is something more raw than that. CIL allows you to specify a pointer to any method with any parameters you want. Let's look at how void(*)() (a pointer to a method with no parameters returning nothing) is translated:

method unmanaged cdecl void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) *()

method is the keyword here – it begins a function type signature, followed by the method's attributes, return type modified by CallConvCdecl, *, and its parameter list.


Primitive types

 

Long (int) has in this implementation the same size as regular int, but the difference is also stored in the signature:

int32 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)

MSDN on IsLong:
The C++ standard indicates that a long value and an integer value are distinct types. However, they are both represented using ELEMENT_TYPE_I4 in an assembly. To distinguish a long from an integer in C++, the Microsoft C++ compiler adds the IsLong modifier to any instance of a long when the instance is emited. This process is critically important for maintaining language-level type safety.
What the documentation forgets is that also double can be long.

float64 modopt([mscorlib]System.Runtime.CompilerServices.IsLong)

It should be noted that all float types in .NET actually use the CPU's long floating point type for computations (called F in CLI, but this is a topic for another article).

Char can be signed, unsigned, or neither. The first is sbyte in C#, the second byte, and without a sign specifier:

int8 modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte)

MSDN on IsSignUnspecifiedByte:
Some programming languages, such as C++, recognize three distinct char values: signed char, unsigned char, and char. To distinguish the unmodified char type from the others, the Microsoft C++ compiler adds the IsSignUnspecifiedByte modifier to each char type emitted to an assembly.


As you can see, there are many CIL features unknown to C#, but used heavily in C++/CLI. My best advice if you want to find more, is to compile some C++/CLI code yourselves, and browse the assembly with ildasm or ILSpy. Have fun!

July 31, 2015

The Cloneable pattern

For most languages that deal with OOP, one concept is always quite hard to approach. The cloning of objects. First of all, there are two implementational methods of cloning – deep cloning and shallow cloning. Deep cloning analyzes the whole structure of the object and the objects the instance references, and provides a complete copy, separated from the original structure. Shallow copy, on the other hand, only copies the most accessible data, the technical value of the object (in C#, values of all fields).
In C#, shallow copy of the current object is provided by the protected method MemberwiseClone, which is almost totally useless (good only for simple sealed classes). Not only it isn't accessible outside the object, but in most cases, you cannot use it to help you with implementing your own cloning, as it returns an already initialized object.
Fortunately, there is an interface which is used for this purpose – ICloneable. However, there is a commonly adressed problem about this interface: does it mean deep or shallow copy?
In turns out, neither. This is what the documentation says:
Supports cloning, which creates a new instance of a class with the same value as an existing instance.
Now what is the value of an object? The technical value are the values of all non-static fields of the instance, including references, but the semantical value depends on the semantical meaning of those fields. A field (or a property) can mean two things: association and composition (used mostly in C++). Association simply associates two objects, they reference each other, but do not depend on each other. Composition puts objects into ownership state, where one object owns other objects, which can't exist without the owner. The IDisposable pattern is similar to composition, when there are resources that are disposed if the owner is disposed (even if they are referenced outside the object).
So a field basically means two things: "I exist outside of this object, and the object only uses me", or "I am part of this object, and I can't exist without it". The second meaning is what makes the semantical value of the object.
Unfortunately, C# doesn't provide the means to differentiate between those meanings (it is similar to C++/CLI reference types with value-type semantics, like System::Object without the ^). If I have a Wall that contains a Window, it is in the ownership relation, and thus cloning it should yield a new wall with a new window. On the other hand, if the wall keeps a reference to the House it is in, cloning shouldn't create a new house.
Enough theory, how to implement it?

public class House
{
    
}

public class Wall : ICloneable
{
    public Window Window{getprivate set;}
    public House House{getprivate set;}
    
    protected Wall(Wall prototype)
    {
        Window = (Window)prototype.Window.Clone(); //creates a new window
        House = prototype.House; //keeps one house 
    }
    
    public virtual object Clone()
    {
        return new Wall(this);
    }
}

public class Window : ICloneable
{
    public int Size{getprivate set;}
    
    protected Window(Window prototype)
    {
        Size = prototype.Size;
    }
    
    public virtual object Clone()
    {
        return new Window(this);
    }
}

This utilizes the copy-constructor technique to initialize an object from a prototype, and allows extensibility for derived classes to implement their own cloning. The copy-constructor is protected to make programmers use the Clone method instead of the constructor.
A problem with this approach is that the cloning method doesn't specify what it returns, although it it the part of the contract.

public class Wall : ICloneable
{
    public Window Window{getprivate set;}
    public House House{getprivate set;}
    
    protected Wall(Wall prototype)
    {
        Window = prototype.Window.Clone();
        House = prototype.House;
    }
}

public class Window : ICloneable
{
    public int Size{getprivate set;}
  
    protected Window(Window prototype)
    {
        Size = prototype.Size;
    }
  
    object ICloneable.Clone()
    {
        return CloneImpl();
    }
    public Window Clone()
    {
        return (Window)CloneImpl();
    }
    protected virtual object CloneImpl()
    {
        return new Window(this);
    }
}

public class TrueWindow : Window
{
    protected TrueWindow(TrueWindow prototype) : base(prototype)
    {
      
    }
  
    public new TrueWindow Clone()
    {
        return (TrueWindow)CloneImpl();
    }
    protected override object CloneImpl()
    {
        return new TrueWindow(this);
    }
} 

There is no real way for the ICloneable interface to limit the implementing class to return itself, but at least this way it is apparent for the outside that it does so, at the cost of three methods in the base class and two methods in each derived class.
Or is there are way to limit it better? What if we introduce a generic ICloneable<T> interface to do it? Well, let's see:

public interface ICloneable<out T> : ICloneable where T : ICloneable<T>
{
    new T Clone();
}

public class Wall : ICloneable<Wall>
{
    public Window Window{getprivate set;}
    public House House{getprivate set;}
    
    protected Wall(Wall prototype)
    {
        Window = prototype.Window.Clone();
        House = prototype.House;
    }
    
    object ICloneable.Clone()
    {
        return this.Clone();
    }
    public Wall Clone()
    {
        return (Wall)CloneImpl();
    }
    protected virtual object CloneImpl()
    {
        return new Wall(this);
    }
}

public class Window : ICloneable<Window>
{
    public int Size{getprivate set;}
  
    protected Window(Window prototype)
    {
        Size = prototype.Size;
    }
  
    object ICloneable.Clone()
    {
        return CloneImpl();
    }
    public Window Clone()
    {
        return (Window)CloneImpl();
    }
    protected virtual object CloneImpl()
    {
        return new Window(this);
    }
}

public class TrueWindow : Window, ICloneable<TrueWindow>
{
    protected TrueWindow(TrueWindow prototype) : base(prototype)
    {
      
    }
  
    public new TrueWindow Clone()
    {
        return (TrueWindow)CloneImpl();
    }
    protected override object CloneImpl()
    {
        return new TrueWindow(this);
    }
} 

Not that hard, actually. We've now introduced a contract that an object implementing ICloneable<T> clone-returns T. We can't really limit it to the actual type of the object, but this is the best we can get.
But was it really necessary?
In our attempt to get rid of a cast, we have introduced a new painful-to-implement interface, and lots of other unnecessary methods in all classes. What we really needed was a method that clones the object and casts it to its type. Extension methods to the rescue!

public static T Copy<T>(this T obj) where T : ICloneable
{
    return (T)obj.Clone();
}

The only problem left is cloning structures, which require boxing and unboxing the value. Although structures aren't usually used to represent such complex principles, we can clone them, too:

public struct WallStructure : ICloneable
{
    public Window Window{getprivate set;}
    
    private WallStructure(WallStructure prototype) : this()
    {
        Window = prototype.Window.Clone();
    }
    
    object ICloneable.Clone()
    {
        return Clone();
    }
    
    public WallStructure Clone()
    {
        return new WallStructure(this);
    }
}

As you can see, it is possible and not so hard, but you shouldn't really design structures like that. As structures are passed by value, one might expect that it is the same what Clone does (although if it was, there would be no need of the public method and the copy-constructor at all). ICloneable on structures is useful only when you want to clone the boxed value, not the unboxed one.

I hope I have clarified the correct way of cloning objects, and the semantical value of objects. See you next time!