-
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added test and implementation draft. Need to workaround fastmember I think * copied FastMember and applied necessary changes
- Loading branch information
1 parent
f07c71c
commit 9340505
Showing
22 changed files
with
2,583 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System.Collections; | ||
using System.Runtime.CompilerServices; | ||
using System; | ||
using Microsoft.CSharp.RuntimeBinder; | ||
|
||
namespace FastMember | ||
{ | ||
internal static class CallSiteCache | ||
{ | ||
private static readonly Hashtable getters = new Hashtable(), setters = new Hashtable(); | ||
|
||
internal static object GetValue(string name, object target) | ||
{ | ||
CallSite<Func<CallSite, object, object>> callSite = (CallSite<Func<CallSite, object, object>>)getters[name]; | ||
if (callSite == null) | ||
{ | ||
CallSite<Func<CallSite, object, object>> newSite = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, name, typeof(CallSiteCache), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); | ||
lock (getters) | ||
{ | ||
callSite = (CallSite<Func<CallSite, object, object>>)getters[name]; | ||
if (callSite == null) | ||
{ | ||
getters[name] = callSite = newSite; | ||
} | ||
} | ||
} | ||
return callSite.Target(callSite, target); | ||
} | ||
internal static void SetValue(string name, object target, object value) | ||
{ | ||
CallSite<Func<CallSite, object, object, object>> callSite = (CallSite<Func<CallSite, object, object, object>>)setters[name]; | ||
if (callSite == null) | ||
{ | ||
CallSite<Func<CallSite, object, object, object>> newSite = CallSite<Func<CallSite, object, object, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, name, typeof(CallSiteCache), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) })); | ||
lock (setters) | ||
{ | ||
callSite = (CallSite<Func<CallSite, object, object, object>>)setters[name]; | ||
if (callSite == null) | ||
{ | ||
setters[name] = callSite = newSite; | ||
} | ||
} | ||
} | ||
callSite.Target(callSite, target, value); | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
namespace FastMember | ||
{ | ||
/// <summary> | ||
/// Represents an abstracted view of the members defined for a type | ||
/// </summary> | ||
public sealed class MemberSet : IEnumerable<Member>, IList<Member> | ||
{ | ||
Member[] members; | ||
internal MemberSet(Type type) | ||
{ | ||
const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance; | ||
members = type.GetTypeAndInterfaceProperties(PublicInstance).Cast<MemberInfo>().Concat(type.GetFields(PublicInstance).Cast<MemberInfo>()).OrderBy(x => x.Name) | ||
.Select(member => new Member(member)).ToArray(); | ||
} | ||
/// <summary> | ||
/// Return a sequence of all defined members | ||
/// </summary> | ||
public IEnumerator<Member> GetEnumerator() | ||
{ | ||
foreach (var member in members) yield return member; | ||
} | ||
/// <summary> | ||
/// Get a member by index | ||
/// </summary> | ||
public Member this[int index] | ||
{ | ||
get { return members[index]; } | ||
} | ||
/// <summary> | ||
/// The number of members defined for this type | ||
/// </summary> | ||
public int Count { get { return members.Length; } } | ||
Member IList<Member>.this[int index] | ||
{ | ||
get { return members[index]; } | ||
set { throw new NotSupportedException(); } | ||
} | ||
|
||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } | ||
bool ICollection<Member>.Remove(Member item) { throw new NotSupportedException(); } | ||
void ICollection<Member>.Add(Member item) { throw new NotSupportedException(); } | ||
void ICollection<Member>.Clear() { throw new NotSupportedException(); } | ||
void IList<Member>.RemoveAt(int index) { throw new NotSupportedException(); } | ||
void IList<Member>.Insert(int index, Member item) { throw new NotSupportedException(); } | ||
|
||
bool ICollection<Member>.Contains(Member item) => members.Contains(item); | ||
void ICollection<Member>.CopyTo(Member[] array, int arrayIndex) { members.CopyTo(array, arrayIndex); } | ||
bool ICollection<Member>.IsReadOnly { get { return true; } } | ||
int IList<Member>.IndexOf(Member member) { return Array.IndexOf<Member>(members, member); } | ||
|
||
} | ||
/// <summary> | ||
/// Represents an abstracted view of an individual member defined for a type | ||
/// </summary> | ||
public sealed class Member | ||
{ | ||
private readonly MemberInfo member; | ||
internal Member(MemberInfo member) | ||
{ | ||
this.member = member; | ||
} | ||
/// <summary> | ||
/// The ordinal of this member among other members. | ||
/// Returns -1 in case the ordinal is not set. | ||
/// </summary> | ||
public int Ordinal | ||
{ | ||
get | ||
{ | ||
var ordinalAttr = member.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(OrdinalAttribute)); | ||
|
||
if (ordinalAttr == null) | ||
{ | ||
return -1; | ||
} | ||
|
||
// OrdinalAttribute class must have only one constructor with a single argument. | ||
return Convert.ToInt32(ordinalAttr.ConstructorArguments.Single().Value); | ||
} | ||
} | ||
/// <summary> | ||
/// The name of this member | ||
/// </summary> | ||
public string Name { get { return member.Name; } } | ||
/// <summary> | ||
/// The type of value stored in this member | ||
/// </summary> | ||
public Type Type | ||
{ | ||
get | ||
{ | ||
if(member is FieldInfo) return ((FieldInfo)member).FieldType; | ||
if (member is PropertyInfo) return ((PropertyInfo)member).PropertyType; | ||
throw new NotSupportedException(member.GetType().Name); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Is the attribute specified defined on this type | ||
/// </summary> | ||
public bool IsDefined(Type attributeType) | ||
{ | ||
if (attributeType == null) throw new ArgumentNullException(nameof(attributeType)); | ||
return Attribute.IsDefined(member, attributeType); | ||
} | ||
|
||
/// <summary> | ||
/// Getting Attribute Type | ||
/// </summary> | ||
public Attribute GetAttribute(Type attributeType, bool inherit) | ||
=> Attribute.GetCustomAttribute(member, attributeType, inherit); | ||
|
||
/// <summary> | ||
/// Property Can Write | ||
/// </summary> | ||
public bool CanWrite | ||
{ | ||
get | ||
{ | ||
switch (member.MemberType) | ||
{ | ||
case MemberTypes.Field: return true; | ||
case MemberTypes.Property: return ((PropertyInfo)member).CanWrite; | ||
default: throw new NotSupportedException(member.MemberType.ToString()); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Property Can Read | ||
/// </summary> | ||
public bool CanRead | ||
{ | ||
get | ||
{ | ||
switch (member.MemberType) | ||
{ | ||
case MemberTypes.Field: return true; | ||
case MemberTypes.Property: return ((PropertyInfo)member).CanRead; | ||
default: throw new NotSupportedException(member.MemberType.ToString()); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.