Skip to content

Commit be23460

Browse files
committed
Fixed issue #2
Fixed issue #2
1 parent 6dd6524 commit be23460

File tree

8 files changed

+135
-96
lines changed

8 files changed

+135
-96
lines changed

src-console/System.Linq.Dynamic.Core.ConsoleTestApp/Program.cs

+23-14
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,28 @@
55
using System.Linq.Expressions;
66
using System.Reflection;
77

8-
98
namespace System.Linq.Dynamic.Core.ConsoleTestApp
109
{
1110
public static class E
1211
{
13-
public static IQueryable<IGrouping<TKey, TSource>> GroupBy2<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
12+
public static IQueryable GroupBy2<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keyLambda2)
1413
{
15-
return source.Provider.CreateQuery<IGrouping<TKey, TSource>>(
16-
Expression.Call(
17-
typeof(Queryable), "GroupBy",
18-
new Type[] { source.ElementType, keySelector.Body.Type },
19-
new Expression[] { source.Expression, Expression.Quote(keySelector) }
20-
));
14+
//LambdaExpression keyLambda = DynamicExpression.ParseLambda(source.ElementType, null, "new (Profile.Age)", null);
15+
LambdaExpression x = (LambdaExpression)keyLambda2;
16+
17+
//return source.Provider.CreateQuery<IGrouping<TKey, TSource>>(
18+
// Expression.Call(
19+
// typeof(Queryable), "GroupBy",
20+
// new Type[] { source.ElementType, keySelector.Body.Type },
21+
// new Expression[] { source.Expression, Expression.Quote(keySelector) }
22+
// ));
23+
24+
25+
return source.Provider.CreateQuery(
26+
Expression.Call(
27+
typeof(Queryable), "GroupBy",
28+
new Type[] { source.ElementType, x.Body.Type },
29+
new Expression[] { source.Expression, Expression.Quote(x) }));
2130
}
2231
}
2332

@@ -39,20 +48,20 @@ public static void Main(string[] args)
3948

4049
private static void GroupByAndSelect_TestDynamicSelectMember()
4150
{
42-
43-
44-
//Arrange
45-
var testList = User.GenerateSampleModels(51);
51+
var testList = User.GenerateSampleModels(51).Where(u => u.Profile.Age < 23);
4652
var qry = testList.AsQueryable();
4753

4854
var rrrr = qry.GroupBy2(x => new { x.Profile.Age });
55+
var ll = rrrr.ToDynamicList();
4956

5057
var byAgeReturnAllReal = qry.GroupBy(x => new { x.Profile.Age }).ToList();
5158
var r1 = byAgeReturnAllReal[0];
5259

53-
var byAgeReturnAll = qry.GroupBy("new (Profile.Age as Age)").OrderBy("Key.Age").ToDynamicList();
60+
//var byAgeReturnOK = qry.GroupBy("Profile.Age").ToDynamicList();
61+
62+
// - [0] {System.Linq.Grouping<<>f__AnonymousType0<int?>, System.Linq.Dynamic.Core.Tests.Helpers.Models.User>} object {System.Linq.Grouping<<>f__AnonymousType0<int?>, System.Linq.Dynamic.Core.Tests.Helpers.Models.User>}
63+
var byAgeReturnAll = qry.GroupBy("new (Profile.Age)").OrderBy("Key.Age").ToDynamicList();
5464
var q1 = byAgeReturnAll[0];
55-
var q2 = byAgeReturnAll[50];
5665

5766
var k = q1.Key;
5867
int? age = k.Age;

src/System.Linq.Dynamic.Core/ClassFactory.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,14 @@ private static FieldInfo[] GenerateProperties(TypeBuilder tb, DynamicProperty[]
133133
FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, FieldAttributes.Private);
134134
PropertyBuilder pb = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, null);
135135

136-
MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name, getSetAttr, dp.Type, Type.EmptyTypes);
136+
MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name, getSetAttr, dp.Type, new Type[0]);
137137
ILGenerator genGet = mbGet.GetILGenerator();
138138
genGet.Emit(OpCodes.Ldarg_0);
139139
genGet.Emit(OpCodes.Ldfld, fb);
140140
genGet.Emit(OpCodes.Ret);
141141
pb.SetGetMethod(mbGet);
142142

143-
MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name, getSetAttr, null, new Type[] { dp.Type });
143+
MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name, getSetAttr, null, new[] { dp.Type });
144144

145145
// workaround for https://github.com/dotnet/corefx/issues/7792
146146
mbSet.DefineParameter(1, ParameterAttributes.In, "_" + dp.Name);
@@ -200,7 +200,7 @@ private static void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields)
200200
MethodBuilder mb = tb.DefineMethod("GetHashCode",
201201
MethodAttributes.Public | MethodAttributes.ReuseSlot |
202202
MethodAttributes.Virtual | MethodAttributes.HideBySig,
203-
typeof(int), Type.EmptyTypes);
203+
typeof(int), new Type[0]);
204204
ILGenerator gen = mb.GetILGenerator();
205205
gen.Emit(OpCodes.Ldc_I4_0);
206206
foreach (FieldInfo field in fields)
@@ -210,7 +210,7 @@ private static void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields)
210210
gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);
211211
gen.Emit(OpCodes.Ldarg_0);
212212
gen.Emit(OpCodes.Ldfld, field);
213-
gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null);
213+
gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new[] { ft }), null);
214214
gen.Emit(OpCodes.Xor);
215215
}
216216
gen.Emit(OpCodes.Ret);
@@ -260,4 +260,4 @@ public bool Equals(Signature other)
260260
}
261261
}
262262
}
263-
}
263+
}

src/System.Linq.Dynamic.Core/DynamicClass.cs

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Reflection;
2-
using System.Text;
32

43
namespace System.Linq.Dynamic.Core
54
{
@@ -23,5 +22,32 @@ public void SetDynamicProperty<T>(string propertyName, T value)
2322

2423
propInfo.SetValue(this, value, null);
2524
}
25+
26+
//protected bool Equals(DynamicClass other)
27+
//{
28+
// var properties = GetType().GetProperties();
29+
// foreach (var property in properties)
30+
// {
31+
// var thisValue = property.GetValue(this, null);
32+
// var otherValue = property.GetValue(other, null);
33+
34+
// if (thisValue != null && !thisValue.Equals(otherValue))
35+
// return false;
36+
37+
// if (otherValue != null && !otherValue.Equals(thisValue))
38+
// return false;
39+
// }
40+
41+
// return true;
42+
//}
43+
44+
//public override bool Equals(object obj)
45+
//{
46+
// if (ReferenceEquals(null, obj)) return false;
47+
// if (ReferenceEquals(this, obj)) return true;
48+
// if (obj.GetType() != this.GetType()) return false;
49+
50+
// return Equals((DynamicClass)obj);
51+
//}
2652
}
2753
}

src/System.Linq.Dynamic.Core/DynamicClassFactory.cs

+18-18
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,33 @@
1010
using JetBrains.Annotations;
1111
using System.Linq.Dynamic.Core.Extensions;
1212

13-
#if NETSTANDARD1_0
14-
using BindingFlags = System.Reflection.BindingFlags;
15-
#endif
16-
1713
namespace System.Linq.Dynamic.Core
1814
{
1915
/// <summary>
2016
/// http://stackoverflow.com/questions/29413942/c-sharp-anonymous-object-with-properties-from-dictionary
2117
/// </summary>
2218
internal static class DynamicClassFactory
2319
{
20+
// EmptyTypes is used to indicate that we are looking for someting without any parameters.
21+
private readonly static Type[] EmptyTypes = new Type[0];
22+
2423
private static readonly ConcurrentDictionary<string, Type> GeneratedTypes = new ConcurrentDictionary<string, Type>();
2524

2625
private static readonly ModuleBuilder ModuleBuilder;
2726

2827
// Some objects we cache
29-
private static readonly CustomAttributeBuilder CompilerGeneratedAttributeBuilder = new CustomAttributeBuilder(typeof(CompilerGeneratedAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
28+
private static readonly CustomAttributeBuilder CompilerGeneratedAttributeBuilder = new CustomAttributeBuilder(typeof(CompilerGeneratedAttribute).GetConstructor(EmptyTypes), new object[0]);
3029
private static readonly CustomAttributeBuilder DebuggerBrowsableAttributeBuilder = new CustomAttributeBuilder(typeof(DebuggerBrowsableAttribute).GetConstructor(new[] { typeof(DebuggerBrowsableState) }), new object[] { DebuggerBrowsableState.Never });
31-
private static readonly CustomAttributeBuilder DebuggerHiddenAttributeBuilder = new CustomAttributeBuilder(typeof(DebuggerHiddenAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
30+
private static readonly CustomAttributeBuilder DebuggerHiddenAttributeBuilder = new CustomAttributeBuilder(typeof(DebuggerHiddenAttribute).GetConstructor(EmptyTypes), new object[0]);
3231

33-
private static readonly ConstructorInfo ObjectCtor = typeof(object).GetConstructor(Type.EmptyTypes);
32+
private static readonly ConstructorInfo ObjectCtor = typeof(object).GetConstructor(EmptyTypes);
3433
#if DNXCORE50 || DOTNET5_4 || NETSTANDARD1_0
3534
private static readonly MethodInfo ObjectToString = typeof(object).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public);
3635
#else
37-
private static readonly MethodInfo ObjectToString = typeof(object).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
36+
private static readonly MethodInfo ObjectToString = typeof(object).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, EmptyTypes, null);
3837
#endif
3938

40-
private static readonly ConstructorInfo StringBuilderCtor = typeof(StringBuilder).GetConstructor(Type.EmptyTypes);
39+
private static readonly ConstructorInfo StringBuilderCtor = typeof(StringBuilder).GetConstructor(EmptyTypes);
4140
#if DNXCORE50 || DOTNET5_4 || NETSTANDARD1_0
4241
private static readonly MethodInfo StringBuilderAppendString = typeof(StringBuilder).GetMethod("Append", new[] { typeof(string) });
4342
private static readonly MethodInfo StringBuilderAppendObject = typeof(StringBuilder).GetMethod("Append", new[] { typeof(object) });
@@ -48,14 +47,14 @@ internal static class DynamicClassFactory
4847

4948
private static readonly Type EqualityComparer = typeof(EqualityComparer<>);
5049

51-
#if DNXCORE50 || DOTNET5_4 || NETSTANDARD1_0
50+
5251
private static readonly Type EqualityComparerGenericArgument = EqualityComparer.GetGenericArguments()[0];
52+
#if DNXCORE50 || DOTNET5_4 || NETSTANDARD1_0
5353
private static readonly MethodInfo EqualityComparerDefault = EqualityComparer.GetMethod("get_Default", BindingFlags.Static | BindingFlags.Public);
5454
private static readonly MethodInfo EqualityComparerEquals = EqualityComparer.GetMethod("Equals", new[] { EqualityComparerGenericArgument, EqualityComparerGenericArgument });
5555
private static readonly MethodInfo EqualityComparerGetHashCode = EqualityComparer.GetMethod("GetHashCode", new[] { EqualityComparerGenericArgument });
5656
#else
57-
private static readonly Type EqualityComparerGenericArgument = EqualityComparer.GetGenericArguments()[0];
58-
private static readonly MethodInfo EqualityComparerDefault = EqualityComparer.GetMethod("get_Default", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null);
57+
private static readonly MethodInfo EqualityComparerDefault = EqualityComparer.GetMethod("get_Default", BindingFlags.Static | BindingFlags.Public, null, EmptyTypes, null);
5958
private static readonly MethodInfo EqualityComparerEquals = EqualityComparer.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public, null, new[] { EqualityComparerGenericArgument, EqualityComparerGenericArgument }, null);
6059
private static readonly MethodInfo EqualityComparerGetHashCode = EqualityComparer.GetMethod("GetHashCode", BindingFlags.Instance | BindingFlags.Public, null, new[] { EqualityComparerGenericArgument }, null);
6160
#endif
@@ -124,7 +123,7 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties)
124123
}
125124

126125
// .ctor default
127-
ConstructorBuilder constructorDef = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, Type.EmptyTypes);
126+
ConstructorBuilder constructorDef = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, EmptyTypes);
128127
constructorDef.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
129128

130129
ILGenerator ilgeneratorConstructorDef = constructorDef.GetILGenerator();
@@ -177,7 +176,7 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties)
177176

178177
ilgeneratorConstructor.Emit(OpCodes.Stfld, fields[i]);
179178

180-
PropertyBuilder property = tb.DefineProperty(names[i], PropertyAttributes.None, CallingConventions.HasThis, generics[i], Type.EmptyTypes);
179+
PropertyBuilder property = tb.DefineProperty(names[i], PropertyAttributes.None, CallingConventions.HasThis, generics[i], EmptyTypes);
181180

182181
// getter
183182
MethodBuilder getter = tb.DefineMethod($"get_{names[i]}", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, generics[i], null);
@@ -191,7 +190,7 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties)
191190
// setter
192191
MethodBuilder setter = tb.DefineMethod($"set_{names[i]}", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, null, new[] { generics[i] });
193192
setter.SetCustomAttribute(CompilerGeneratedAttributeBuilder);
194-
193+
195194
// workaround for https://github.com/dotnet/corefx/issues/7792
196195
setter.DefineParameter(1, ParameterAttributes.In, generics[i].Name);
197196

@@ -204,7 +203,7 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties)
204203
}
205204

206205
// ToString()
207-
MethodBuilder toString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(string), Type.EmptyTypes);
206+
MethodBuilder toString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(string), EmptyTypes);
208207
toString.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
209208
ILGenerator ilgeneratorToString = toString.GetILGenerator();
210209
ilgeneratorToString.DeclareLocal(typeof(StringBuilder));
@@ -214,7 +213,8 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties)
214213
// Equals
215214
MethodBuilder equals = tb.DefineMethod("Equals", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(bool), new[] { typeof(object) });
216215
equals.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
217-
equals.DefineParameter(1, ParameterAttributes.None, "value");
216+
equals.DefineParameter(1, ParameterAttributes.In, "value");
217+
218218
ILGenerator ilgeneratorEquals = equals.GetILGenerator();
219219
ilgeneratorEquals.DeclareLocal(tb);
220220
ilgeneratorEquals.Emit(OpCodes.Ldarg_1);
@@ -225,7 +225,7 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties)
225225
Label equalsLabel = ilgeneratorEquals.DefineLabel();
226226

227227
// GetHashCode()
228-
MethodBuilder getHashCode = tb.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int), Type.EmptyTypes);
228+
MethodBuilder getHashCode = tb.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int), EmptyTypes);
229229
getHashCode.SetCustomAttribute(DebuggerHiddenAttributeBuilder);
230230
ILGenerator ilgeneratorGetHashCode = getHashCode.GetILGenerator();
231231
ilgeneratorGetHashCode.DeclareLocal(typeof(int));

src/System.Linq.Dynamic.Core/DynamicExpression.cs

+2-23
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,9 @@ namespace System.Linq.Dynamic.Core
55
{
66
internal static class DynamicExpression
77
{
8-
//Commented Out as It's never used.
9-
//public static Expression Parse(Type resultType, string expression, params object[] values)
10-
//{
11-
// ExpressionParser parser = new ExpressionParser(null, expression, values);
12-
// return parser.Parse(resultType);
13-
//}
14-
158
public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values)
169
{
17-
return ParseLambda(new ParameterExpression[] { Expression.Parameter(itType, "") }, resultType, expression, values);
10+
return ParseLambda(new[] { Expression.Parameter(itType, "") }, resultType, expression, values);
1811
}
1912

2013
public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values)
@@ -23,24 +16,10 @@ public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Typ
2316
return Expression.Lambda(parser.Parse(resultType), parameters);
2417
}
2518

26-
//Commented Out as It's never used.
27-
//public static Expression<Func<T, S>> ParseLambda<T, S>(string expression, params object[] values)
28-
//{
29-
// return (Expression<Func<T, S>>)ParseLambda(typeof(T), typeof(S), expression, values);
30-
//}
31-
32-
//Commented Out as It's never used.
33-
//public static Type CreateClass(params DynamicProperty[] properties)
34-
//{
35-
// return ClassFactory.Instance.GetDynamicClass(properties);
36-
//}
37-
38-
#if !NETFX_CORE
39-
public static Type CreateClass(IList<DynamicProperty> properties)
19+
public static Type CreateType(IList<DynamicProperty> properties)
4020
{
4121
return DynamicClassFactory.CreateType(properties);
4222
//return ClassFactory.Instance.CreateType(properties);
4323
}
44-
#endif
4524
}
4625
}

0 commit comments

Comments
 (0)