Yes, technically your issue here is that you are trying to bind object of type PropertyInfo
to another object of same type.
Also It's not very clear what you try to do here - if source property value is null, you are trying to bind it's value to destination property, which should not happen.
Code should probably re-arranged and depend on what behavior you specifically are trying to achieve: deep copy of reference-types, simple reference copy, how to treat collections, etc...
I modified code a bit to show the idea:
public static void Bind(this object destination, object source)
{
if (source != null)
{
var destProperties = destination.GetType().GetProperties();
foreach (var sourceProperty in source.GetType().GetProperties())
{
var availableDestinationProperties = destProperties.Where(x=>x.Name == sourceProperty.Name && x.PropertyType.IsAssignableFrom(sourceProperty.PropertyType));
if (availableDestinationProperties.Count() == 0)
{
continue;
}
var destProperty = availableDestinationProperties.Single();
var sourcePropertyValue = sourceProperty.GetValue(source, null);
var destPropertyType = destProperty.PropertyType;
if (sourcePropertyValue != null)
{
if (IsCollection(destPropertyType))
{
//handle collections: either do collection item references copy, do deep copy of each element in collection, etc..
}
if (IsReferenceType(destPropertyType))
{
//do deep copy with recursion: create object OR do reference copy in case you need this
}
destProperty.SetValue(destination, sourcePropertyValue, new object[] { });
}
}
}
}
With time number of those conditions will grow and you will have to have a lot of tests to verify stuff works fine.
If you write a small-to-medium sized application, you can still use AutoMapper, it's not that slow. If you don't specifically like it, there are other 3rd party libs that can do it - you can see question like this one, for instance: Alternatives to AutoMapper
It looks like it's not worth for you to reinvent the wheel.