Allows you to use prototypal inheritance in C#
C#
Latest commit e8a48db Mar 23, 2013 @jwcarroll jwcarroll Fixing typo in readme
Permalink
Failed to load latest commit information.
.nuget
ProtoSharp.Tests
ProtoSharp
.gitignore
ProtoSharp.sln
README.md

README.md

ProtoSharp

ProtoSharp allows you to simulate prototypal inheritence using the Dynamic Language Runtime features added in .Net 4

ProtoSharp is primarily a thought experiment, and an example of how we can augment C# with dynamic features using the DLR.

What does it look like?

By inheriting from ProtoObject, you can add new members to a type dynamically at runtime.

public class Foo: ProtoObject {}
public class Bar: Foo {}

dynamic myFoo = new Foo();
dynamic yourFoo = new Foo();
dynamic myBar = new Bar();

myFoo.Prototype.Name = "Josh";
myFoo.Prototype.SayHello = new Action(s => Console.WriteLine("Hello, " + s));

yourFoo.SayHello(myBar.Name); // 'Hello, Josh'

Preserving member state

Becuase ProtoSharp walks the inheritence chain, members can be overriden on any single instance.

public class Parent: ProtoObject {}
public class Child: ProtoObject {}

dynamic dad = new Parent();
dynamic son = new Child();
dynamic daughter = new Child();

dad.Prototype.Name = "Josh";
daughter.Name = "Hadassah";

Console.Write(dad.Name); // "Josh"
Console.Write(son.Name); // "Josh"
Console.Write(daughter.Name); // "Hadassah"

Checking for 'Undefined'

You might need to check for the existence of a member before trying to use it. ProtoSharp makes this easy using the Proto helper class.

dynamic obj = new ProtoObject();

//Evaluates to true since Name does not exist
if(obj.Name == Proto.Undefined){
   Console.Write("Name is Undefined");
}

Accessing this from dynamically added methods

Adding methods dynamically isn't all that useful unless you can access the current instance. Luckily the Proto helper class provides a thread safe way of accessing the current instance for dynamic methods.

dynamic obj = new ProtoObject();
dynamic obj2 = new ProtoObject();
dynamic obj3 = new ProtoObject();

obj.Prototype.Name = "Josh";
obj.Prototype.SayHello = (Func<String>)(() => {
    //Get a reference to the current instance
    dynamic @this = Proto.CurrentContext;

    return String.Format("Hello, {0}!", @this.Name);
});

obj2.Name = "Dan";
obj3.Name = "Kathy";

Console.Write(obj.SayHello()); // "Hello, Josh!"
Console.Write(obj2.SayHello()); // "Hello, Dan!"
Console.Write(obj3.SayHello()); // "Hello, Kathy!"