I have a Case object that in itself contains a number of objects (see below), that again contains objects.
These objects can inherit from a BaseDto class, that implements the ValidateObject method, that executes a DataAnnotation validator on the current object, thus returning with validation errors, accumulated into a ValidationResult collection.
I would like to transform the following cluttered syntax, to something where I can traverse the object hierarchy of a given object, and for each of the objects (and its children!) that implements ValidateObject, execute it.
I'm feeling kinda stuck at the moment, so I would be grateful for any ideas.
cCase.ValidateObject() &
cCase.Object1.ValidateObject() &
cCase.Object2.ValidateObject() &
cCase.Object3.ValidateObject() &
cCase.Object3.ChildObject1.ValidateObject() &
cCase.Object3.ChildObject2.ValidateObject() &
cCase.Object3.ChildObject3.ValidateObject() &
cCase.Object3.ChildObject4.ValidateObject() &
cCase.Object3.ChildObject4.ChildChildObject1.ValidateObject() &
cCase.Object3.ChildObject5.ValidateObject() &
cCase.Object4.ValidateObject() &
cCase.Object4.ChildObject6.ValidateObject();
I'd use extension methods like this:
public interface IValidatable
{
bool ValidateObject();
}
public static class ValidateExtensions
{
public static bool ValidateAll(this IValidatable item)
{
if (!item.ValidateObject())
return false;
const BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public;
var type = item.GetType();
var props = type.GetProperties(flags).Select(x => x.GetValue(item));
var fields = type.GetFields(flags).Select(x => x.GetValue(item));
return props
.Concat(fields)
.OfType<IValidatable>()
.Select(x => x.ValidateAll())
.All(x => x);
}
}
You need to get all fields, which inherit from a BaseDto class, using reflection:
public abstract class BaseDto
{
public abstract bool ValidateObject();
}
// Sample class without nested fields, requiring validation.
public class Case2 : BaseDto
{
public override bool ValidateObject()
{
Console.WriteLine("Validated: " + ToString());
return false;
}
}
// Sample nested class with nested fields, requiring validation.
public class Case1 : BaseDto
{
private Case2 Object1 = new Case2();
private Case2 Object2 = new Case2();
private Stream stream = new MemoryStream();
public override bool ValidateObject()
{
Console.WriteLine("Validated: " + ToString());
return true;
}
}
public class Case : BaseDto
{
private Case1 Object1 = new Case1();
private Case2 Object2 = new Case2();
// don't touch this field
private Stream stream = new MemoryStream();
private Case1 Object3 = new Case1();
public override bool ValidateObject()
{
Console.WriteLine("Validated: " + ToString());
return true;
}
public bool ValidateAll()
{
if (!ValidateObject()) return false;
return ValidateAll(this);
}
private bool ValidateAll(object o)
{
foreach (FieldInfo fieldInfo in o.GetType().GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public))
{
BaseDto current = fieldInfo.GetValue(o) as BaseDto;
if(current != null)
{
bool result = current.ValidateObject();
if(!result)
{
return false;
}
return ValidateAll(current);
}
}
return true;
}
}
Call ValidateAll() on root object. Inside it traverses all fields, which are derived from BaseDto, validates them and all fields inside them recursively.
It would be cleaner to have each class in the hierarchy override ValidateObject() to validate its child objects:
public override bool ValidateObject()
{
return base.ValidateObject() &
this.Object1.ValidateObject() &
this.Object2.ValidateObject() &
this.Object3.ValidateObject() &
this.Object4.ValidateObject();
}
etc. Then the client can just call ValidateObject() on the root object.
Related
This question already has answers here:
Find a private field with Reflection?
(11 answers)
Closed 1 year ago.
I want to get all fields that have null values but i aint even getting any fields:
[Serializable()]
public class BaseClass
{
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
FixNullString(this);
}
public void FixNullString(object type)
{
try
{
var properties = type.GetType().GetFields();
foreach (var property in from property in properties
let oldValue = property.GetValue(type)
where oldValue == null
select property)
{
property.SetValue(type, GetDefaultValue(property));
}
}
catch (Exception)
{
}
}
public object GetDefaultValue(System.Reflection.FieldInfo value)
{
try
{
if (value.FieldType == typeof(string))
return "";
if (value.FieldType == typeof(bool))
return false;
if (value.FieldType == typeof(int))
return 0;
if (value.FieldType == typeof(decimal))
return 0;
if (value.FieldType == typeof(DateTime))
return new DateTime();
}
catch (Exception)
{
}
return null;
}
}
And then i have a class :
[Serializable()]
public class Settings : BaseClass
{
public bool Value1 { get; set; }
public bool Value2 { get; set; }
}
But when i comes to
var properties = type.GetType().GetFields();
then i get 0 fields, it should find 2 fields.
Is type.getType().GetFields() wrong to use ? or am i sending in the wrong class to the base class?
Type.GetFields methods returns all public fields. Fields that the compiler autogenerates for you are private, so you need to specify correct BindingFlags.
type.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
The fields generated by the compiler corresponding to properties of your class have the CompilerGenerated attribute. Also the compiler will generate get and set methods for handling these fields, depending on the declaration of your property.
From CompilerGeneratedAttribute MSDN documentation:
Distinguishes a compiler-generated element from a user-generated element. This class cannot be inherited.
The name of these fields have the format <PropertyName>k_BackingField,the methods set and get names have the format set_PropertyName and get_PropertyName where PropertyName is the name of property.
For example, your Settings class is compiled as follows:
[Serializable]
public class Settings : BaseClass
{
public Settings(){}
// Properties
[CompilerGenerated]
private bool <Value1>k__BackingField;
[CompilerGenerated]
private bool <Value2>k__BackingField;
[CompilerGenerated]
public void set_Value1(bool value)
{
this.<Value1>k__BackingField = value;
}
[CompilerGenerated]
public bool get_Value1()
{
return this.<Value1>k__BackingField;
}
[CompilerGenerated]
public void set_Value2(bool value)
{
this.<Value2>k__BackingField = value;
}
[CompilerGenerated]
public bool get_Value2()
{
return this.<Value2>k__BackingField;
}
}
If you wish exclude this backing fields you can use this method:
public IEnumerable<FieldInfo> GetFields(Type type)
{
return type
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(f => f.GetCustomAttribute<CompilerGeneratedAttribute>() == null);
}
Value1 and Value2 in your Settings class are properties rather than fields, so you'll need to use GetProperties() to access them.
(Using the { get; set; } syntax tells the compiler that you want a property, but that it should generate the get and set for you, along with a hidden private field that contains the data.)
I have a class inheriting from DynamicObject
In this class I have a TryGetMember that I try to evaluate to a static class.
How can TryGetMember overriden from DynamicObject result in a static class?
TL;DR
Calling code:
dynamic sut = new ReachIn();
sut.myclass.MyInnerStaticClass.MyProperty= "fortytwo";
My DynamicObject class tries to return myclass as the MyClass instance.
internal class ReachIn : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = MyClass; // Does not compile.
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
value = MyClass // Does not compile;
return true;
}
}
and what is returned is here:
internal class MyClass
{
internal static class MyInnerStaticClass
{
public static string MyProperty { get; set; }
}
}
This example is a bit forced. It is just a very simplified example of a dynamic object making private fields, properties, methods (and (not yet) classes) visible for testing purpose. I also know one should not write tests this way but I have an esoteric reason. or because I can.
Regardless of your class design I am going to show that what you are trying to achieve is possible with dynamic types and reflection. Firstly a dynamic object is just an object that can take some string name in method like TryGetMember to perform some action. Secondly with string names and reflection you can perform any operation on your objects. So simple dynamic object implementation that will work with your example looks like this:
internal class ReachIn : DynamicObject
{
private readonly Type type;
private readonly string #namespace;
public ReachIn(Type type = null, string #namespace = null)
{
this.type = type;
this.#namespace = #namespace;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (type == null)
{
result = new ReachIn(Type.GetType($"{#namespace}.{binder.Name}".Trim('.')));
return true;
}
var member = type.GetMember(binder.Name).Single();
if (member.MemberType == MemberTypes.NestedType)
{
result = new ReachIn((Type)member);
}
else if (member.MemberType == MemberTypes.Property)
{
result = ((PropertyInfo)member).GetValue(null);
}
else
{
result = null;
return false;
}
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var member = type.GetMember(binder.Name).Single();
if (member.MemberType == MemberTypes.Property)
{
((PropertyInfo)member).SetValue(null, value);
return true;
}
return false;
}
}
So it will work for a sample class with public modifiers:
public class MyClass
{
public static class MyInnerStaticClass
{
public static string MyProperty { get; set; }
}
}
With this you can set your static property like:
dynamic sut = new ReachIn(#namespace: "ConsoleApp8");
sut.MyClass.MyInnerStaticClass.MyProperty = "safd";
It's tested only with your example so for other cases you would need to provide some additional implementation. Not to mention the performance of it would be very bad because of reflection.
I'm talking about something similar to dynamic. This didn't answer my question, hence this question. I want to have a class that I can add properties to at runtime. It needs to be inherited from the type object.
I've seen inheriting from DynamicObject, but it didn't state how to add properties at run-time. Could some light be shed on this for me pls?
I have a class like this:
public class SomeModel : DynamicObject {
public string SomeMandatoryProperty {get; set;}
}
I'd like to add all properties from another class to this class at runtime. So eg.
SomeModel m = new SomeModel();
m = someOtherClass;
string hi = m.otherClassProp; //Property from other class is added.
string mandatory = m.SomeMandatoryProperty; //From the mandatory property set previously.
I think you are looking for ExpandoObject:
The ExpandoObject class enables you to
add and delete members of its
instances at run time and also to set
and get values of these members. This
class supports dynamic binding, which
enables you to use standard syntax
like sampleObject.sampleMember instead
of more complex syntax like
sampleObject.GetAttribute("sampleMember").
dynamic manager;
manager = new ExpandoObject();
manager.Name = "Allison Brown";
manager.Age = 42;
manager.TeamSize = 10;
You should be able to make use of ExpandoObject instead. An ExpandoObject can have members added or removed at runtime and has very nice support if you want to convert to XML etc.
From MSDN Documentation:
dynamic employee, manager;
employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
manager = new ExpandoObject();
manager.Name = "Allison Brown";
manager.Age = 42;
manager.TeamSize = 10;
You'd want to use the ExpandoObject as you can dynamically add properties as needed. There isn't however a direct way to populate an instance with the values from another object easily. You'll have to add it manually using reflection.
Do you want to write a wrapper object where you could add properties to while still accessing the inner? You may want to consider it that way you don't have to manage two copies of values between two different object instances. I wrote a test class to wrap string objects to demonstrate how you can do this (similar to how the ExpandoObject works). It should give you an idea on how you can do this for your types.
class DynamicString : DynamicObject
{
static readonly Type strType = typeof(string);
private string instance;
private Dictionary<string, object> dynProperties;
public DynamicString(string instance)
{
this.instance = instance;
dynProperties = new Dictionary<string, object>();
}
public string GetPrefixString(string prefix)
{
return String.Concat(prefix, instance);
}
public string GetSuffixString(string suffix)
{
return String.Concat(instance, suffix);
}
public override string ToString()
{
return instance;
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type != typeof(string))
return base.TryConvert(binder, out result);
result = instance;
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var method = strType.GetMethod(binder.Name, args.Select(a => a.GetType()).ToArray());
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(instance, args);
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var members = strType.GetMember(binder.Name);
if (members.Length > 0)
{
var member = members.Single();
switch (member.MemberType)
{
case MemberTypes.Property:
result = ((PropertyInfo)member).GetValue(instance, null);
return true;
break;
case MemberTypes.Field:
result = ((FieldInfo)member).GetValue(instance);
return true;
break;
}
}
return dynProperties.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var ret = base.TrySetMember(binder, value);
if (ret) return true;
dynProperties[binder.Name] = value;
return true;
}
}
If you want to be adventurous, you can define your own meta objects to handle the bindings. You could end up with reusable meta objects for different types and simplify your code immensely. I've been playing with this for a while and have this so far. It doesn't handle dynamically adding properties yet. I won't be working on this any further but I'll just leave it here for reference.
class DynamicString : DynamicObject
{
class DynamicStringMetaObject : DynamicMetaObject
{
public DynamicStringMetaObject(Expression parameter, object value)
: base(parameter, BindingRestrictions.Empty, value)
{
}
public override DynamicMetaObject BindConvert(ConvertBinder binder)
{
if (binder.Type == typeof(string))
{
var valueType = Value.GetType();
return new DynamicMetaObject(
Expression.MakeMemberAccess(
Expression.Convert(Expression, valueType),
valueType.GetProperty("Instance")),
BindingRestrictions.GetTypeRestriction(Expression, valueType));
}
return base.BindConvert(binder);
}
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
{
System.Diagnostics.Trace.WriteLine(String.Format("BindGetMember: {0}", binder.Name));
var valueType = Value.GetType();
var self = Expression.Convert(Expression, valueType);
var valueMembers = valueType.GetMember(binder.Name);
if (valueMembers.Length > 0)
{
return BindGetMember(self, valueMembers.Single());
}
var members = typeof(string).GetMember(binder.Name);
if (members.Length > 0)
{
var instance =
Expression.MakeMemberAccess(
self,
valueType.GetProperty("Instance"));
return BindGetMember(instance, members.Single());
}
return base.BindGetMember(binder);
}
private DynamicMetaObject BindGetMember(Expression instance, MemberInfo member)
{
return new DynamicMetaObject(
Expression.Convert(
Expression.MakeMemberAccess(instance, member),
typeof(object)),
BindingRestrictions.GetTypeRestriction(Expression, Value.GetType())
);
}
}
public string Instance { get; private set; }
public DynamicString(string instance)
{
Instance = instance;
}
public override DynamicMetaObject GetMetaObject(Expression parameter)
{
return new DynamicStringMetaObject(parameter, this);
}
public override string ToString()
{
return Instance;
}
public string GetPrefixString(string prefix)
{
return String.Concat(prefix, Instance);
}
public string GetSuffixString(string suffix)
{
return String.Concat(Instance, suffix);
}
}
How to call protected constructor?
public class Foo{
public Foo(a lot of arguments){}
protected Foo(){}
}
var foo=???
This obviously fails test:
public class FooMock:Foo{}
var foo=new FooMock();
Assert(typeof(Foo), foo.GetType());
Call parameterless protected/private constructor:
Foo foo = (Foo)Activator.CreateInstance(typeof(Foo), true);
Call non-public constructor with parameters:
var foo = (Foo)typeof(Foo)
.GetConstructor(
BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance,
null,
new[] { typeof(double) },
null
)
.Invoke(new object[] { 1.0 });
class Foo
{
private Foo(double x){...}
}
You can only call that from a subclass, basically. Your FooMock class will already be calling the protected constructor, because it's equivalent to:
public class FooMock : Foo
{
public FooMock() : base() // Call the protected base constructor
{
}
}
However, your assertion will fail because the type of object referred to be foo is FooMock, not Foo.
An assertion of the form foo is Foo will pass though.
You can't construct an instance of just Foo by calling the protected constructor directly. The point of it being protected instead of public is to ensure that it's only called by subclasses (or within the text of Foo itself).
It's possible that you could call it with reflection within a full trust context, but I'd urge you not to do so.
The only way to cause a protected constructor to be called is to derive from the class and have the derived class delegate to it or to have a static method create it or some other internal method.
EDIT: What the Skeet said!
You cannot call a protected method - although you can call an internal one (using InternalsVisibleTo attribute). You need to expose it in a different way.
Serj-Tm answered adequately but Activator can do it too:
var foo = (Foo) Activator.CreateInstance(typeof(Foo),
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { 2.0 },
CultureInfo.InvariantCulture);
If you want to avoid repeated reflection cost, you can use expressions.
Here is an example of calling a private constructor with a string value.
private static Func<string, T> CreateInstanceFunc()
{
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
var ctor = typeof(T).GetConstructors(flags).Single(
ctors =>
{
var parameters = ctors.GetParameters();
return parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
});
var value = Expression.Parameter(typeof(string), "value");
var body = Expression.New(ctor, value);
var lambda = Expression.Lambda<Func<string, T>>(body, value);
return lambda.Compile();
}
Save the cost of compiling the function multiple times by storing it in a static field.
private static readonly Lazy<Func<string, T>> CreateInstance = new Lazy<Func<string, T>>(CreateInstanceFunc);
Now you can create the object with
CreateInstance.Value("Hello")
If you need to explicitly call the constructor of you base class in your subclass, you have to use the keyword base
may be this will help:
abstract parent class:
public abstract class Animal
{
private string name;
public Animal(string name)
{
this.Name = name;
}
public Animal() { }
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public virtual void talk()
{
Console.WriteLine("Hi,I am an animal");
}
}
class with protected constructor:
public class Lion : Animal
{
private string yahoo;
protected Lion(string name) : base(name)
{
this.Yahoo = "Yahoo!!!";
}
public string Yahoo
{
get
{
return yahoo;
}
set
{
yahoo = value;
}
}
public Lion() { }
}
class Kiara derived from Lion class :
public class Kiara : Lion
{
public Kiara(string name) : base(name)
{
}
public override void talk()
{
Console.WriteLine("HRRRR I'm a Kiara");
}
public Kiara() { }
}
class Simba derived from Lion class :
public class Simba : Lion
{
public Simba(string name) : base(name)
{
}
public override void talk()
{
Console.WriteLine("HRRRR I'm a {0} and this is my daughter:{1} {2}",
new Simba("Simba").Name,
new Kiara("Kiara").Name,
new Simba("Simba").Yahoo);
}
public Simba() { }
}
implementation in main function:
public static void Main(string[] args)
{
Animal lion = new Simba();
lion.Name = "Simba";
lion.talk();
Animal lion1 = new Kiara();
lion1.Name = "Kiara";
lion1.talk();
}
I have a class, which holds a static dictionary of all existing instances, which are defined at compile time.
Basically it looks like this:
[DataContract]
class Foo
{
private static Dictionary<long, Foo> instances = new Dictionary<long, Foo>();
[DataMember]
private long id;
public static readonly Foo A = Create(1);
public static readonly Foo B = Create(2);
public static readonly Foo C = Create(3);
private static Foo Create(long id)
{
Foo instance = new Foo();
instance.id = id;
instances.Add(instance);
return instance;
}
public static Foo Get(long id)
{
return instances[id];
}
}
There are other fields, and the class is derived, but this doesn't matter for the problem.
Only the id is serialized. When an instance of this type is deserialized, I would like to get the instance that has been created as the static field (A, B or C), using Foo.Get(id) instead of getting a new instance.
Is there a simple way to do this? I didn't find any resources which I was able to understand.
During deserialization it (AFAIK) always uses a new object (FormatterServices.GetUninitializedObject), but to get it to substitute the objects after deserialization (but before they are returned to the caller), you can implement IObjectReference, like so:
[DataContract]
class Foo : IObjectReference { // <===== implement an extra interface
object IObjectReference.GetRealObject(StreamingContext ctx) {
return Get(id);
}
...snip
}
done... proof:
static class Program {
static void Main() {
Foo foo = Foo.Get(2), clone;
DataContractSerializer ser = new DataContractSerializer(typeof(Foo));
using (MemoryStream ms = new MemoryStream()) { // clone it via DCS
ser.WriteObject(ms, foo);
ms.Position = 0;
clone = (Foo)ser.ReadObject(ms);
}
Console.WriteLine(ReferenceEquals(foo, clone)); // true
}
}
Note there are some extra notes on this for partial trust scenarios on MSDN, here.
I had a similar problem and the best solution that I found was adding some wrapper class, that was managing instances of the one needed to be serialized.
I am not sure about the exact signature with Contracts. I used SerializableAttribute, and with it i looked smth. like that:
[Serializable]
class FooSerializableWrapper : ISerializable
{
private readonly long id;
public Foo Foo
{
get
{
return Foo.Get(id);
}
}
public FooSerializableWrapper(Foo foo)
{
id = foo.id;
}
protected FooSerializableWrapper(SerializationInfo info, StreamingContext context)
{
id = info.GetInt64("id");
}
void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("id", id);
}
}
You may be able to get a step towards what you are looking for using OnDeserializingAttribute. However, that will probably only let you set properties (so you could have what amounts to a Copy method that populates all the properties of the current instance using your static instance.
I think if you actually want to return your static instances, you'd probably have to write your own Deserializer...
Untested, but I would assume you could implement a deserializer pretty easily like this:
public class MyDeserializer : System.Xml.Serialization.XmlSerializer
{
protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader)
{
Foo obj = (Foo)base.Deserialize(reader);
return Foo.Get(obj.id);
}
}
Note that you'll have to do something about getting the ID since it is private in your code; Also this assumes you are using XML serialization; Replace the inheritance with whatever you actually are using. And finally, this means you'll have to instantiate this type when deserializing your objects, which may involve changing some code and/or configuration.
No problem, just use 2 classes. In getObject method you get your existing object
[Serializable]
public class McRealObjectHelper : IObjectReference, ISerializable
{
Object m_realObject;
virtual object getObject(McObjectId id)
{
return id.GetObject();
}
public McRealObjectHelper(SerializationInfo info, StreamingContext context)
{
McObjectId id = (McObjectId)info.GetValue("ID", typeof(McObjectId));
m_realObject = getObject(id);
if(m_realObject == null)
return;
Type t = m_realObject.GetType();
MemberInfo[] members = FormatterServices.GetSerializableMembers(t, context);
List<MemberInfo> deserializeMembers = new List<MemberInfo>(members.Length);
List<object> data = new List<object>(members.Length);
foreach(MemberInfo mi in members)
{
Type dataType = null;
if(mi.MemberType == MemberTypes.Field)
{
FieldInfo fi = mi as FieldInfo;
dataType = fi.FieldType;
} else if(mi.MemberType == MemberTypes.Property){
PropertyInfo pi = mi as PropertyInfo;
dataType = pi.PropertyType;
}
try
{
if(dataType != null){
data.Add(info.GetValue(mi.Name, dataType));
deserializeMembers.Add(mi);
}
}
catch (SerializationException)
{
//some fiels are missing, new version, skip this fields
}
}
FormatterServices.PopulateObjectMembers(m_realObject, deserializeMembers.ToArray(), data.ToArray());
}
public object GetRealObject( StreamingContext context )
{
return m_realObject;
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
}
public class McRealObjectBinder: SerializationBinder
{
String assemVer;
String typeVer;
public McRealObjectBinder(String asmName, String typeName)
{
assemVer = asmName;
typeVer = typeName;
}
public override Type BindToType( String assemblyName, String typeName )
{
Type typeToDeserialize = null;
if ( assemblyName.Equals( assemVer ) && typeName.Equals( typeVer ) )
{
return typeof(McRealObjectHelper);
}
typeToDeserialize = Type.GetType( String.Format( "{0}, {1}", typeName, assemblyName ) );
return typeToDeserialize;
}
}
Then, when deserialize:
BinaryFormatter bf = new BinaryFormatter(null, context);
bf.Binder = new McRealObjectBinder(YourType.Assembly.FullName, YourType.FullName);
bf.Deserialize(memStream);