我真的很喜欢动态Lambda表达式,即从字符串中构建一个可与Linq方法一起使用的lambda谓词。我可以看到将来的用途。
我想知道是否可以模拟Type。第一步,我从System.Type派生了一个类,因此我可以放置断点以查看调用的内容。我已经提供了我认为是直通实施方式,但它没有计划。
我在行上收到错误Specified method is not supported
var e = myAlias.DynamicExpression.ParseLambda(paramExps, null, expression);
即使我可以看到它通过了正确的方法信息。我的“实验控制”是可以正常工作的标准typeof(Class1)
。您可以通过成对(取消)注释
//Type paramtype = typeof(Class1);
Type paramtype = new MyType() ;
这是来自控制台应用程序的完整列表。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using myAlias = System.Linq.Dynamic; //install-package 'System.Linq.Dynamic' v.1.0.7 with NuGet
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Class1> myList = new List<Class1>();
for (int i = 0; i < 10; i++)
{
Class1 obj1 = new Class1();
obj1.SetFoo(i);
Debug.Assert(obj1.Foo() == i);
myList.Add(obj1);
}
string expression = "o.Foo()<5";
/*
* STACK OVERFLOWERS: switch the following two lines (uncomment one, comment other)
*/
//Type paramtype = typeof(Class1);
Type paramtype = new MyType() ;
ParameterExpression[] paramExps = null;
{
List<ParameterExpression> pList = new List<ParameterExpression>();
var p = Expression.Parameter(paramtype, "o");
pList.Add(p);
paramExps = pList.ToArray();
}
var e = myAlias.DynamicExpression.ParseLambda(paramExps, null, expression);
Delegate compiled = e.Compile();
System.Func<Class1, bool> pred = (System.Func<Class1, bool>)compiled;
List<Class1> newList = new List<Class1>();
newList = (List<Class1>)myList.Where(pred).ToList();
}
}
class MyType : System.Type
{
public string myElementType = null;
Type typClass1 = typeof(Class1);
public override Guid GUID => typClass1.GUID;
public override Module Module => typClass1.Module;
public override Assembly Assembly => typClass1.Assembly;
public override string FullName => typClass1.FullName;
public override string Namespace => typClass1.Namespace;
public override string AssemblyQualifiedName => typClass1.AssemblyQualifiedName;
public override Type BaseType => typClass1.BaseType;
public override Type UnderlyingSystemType => typClass1.UnderlyingSystemType;
public override string Name => typClass1.Name;
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => typClass1.GetConstructors(bindingAttr);
public override object[] GetCustomAttributes(bool inherit) => typClass1.GetCustomAttributes(inherit);
public override object[] GetCustomAttributes(Type attributeType, bool inherit) => typClass1.GetCustomAttributes(attributeType, inherit);
public override Type GetElementType() => typClass1.GetElementType();
public override EventInfo GetEvent(string name, BindingFlags bindingAttr) => typClass1.GetEvent(name, bindingAttr);
public override EventInfo[] GetEvents(BindingFlags bindingAttr) => typClass1.GetEvents(bindingAttr);
public override FieldInfo GetField(string name, BindingFlags bindingAttr) => typClass1.GetField(name, bindingAttr);
public override FieldInfo[] GetFields(BindingFlags bindingAttr) => typClass1.GetFields(bindingAttr);
public override Type GetInterface(string name, bool ignoreCase) => typClass1.GetInterface(name, ignoreCase);
public override Type[] GetInterfaces() => typClass1.GetInterfaces();
public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => typClass1.GetMembers(bindingAttr);
public override MethodInfo[] GetMethods(BindingFlags bindingAttr) => typClass1.GetMethods(bindingAttr);
public override Type GetNestedType(string name, BindingFlags bindingAttr) => typClass1.GetNestedType(name, bindingAttr);
public override Type[] GetNestedTypes(BindingFlags bindingAttr) => typClass1.GetNestedTypes(bindingAttr);
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => typClass1.GetProperties(bindingAttr);
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
{
return typClass1.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
public override bool IsDefined(Type attributeType, bool inherit) => typClass1.IsDefined(attributeType, inherit);
protected override TypeAttributes GetAttributeFlagsImpl() => typClass1.Attributes;
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
return typClass1.GetConstructor(bindingAttr, binder, callConvention, types, modifiers);
}
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
return base.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
}
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
{
return typClass1.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
}
//https://docs.microsoft.com/en-us/dotnet/api/system.type.haselementtypeimpl?view=netframework-4.7.2
protected override bool HasElementTypeImpl() => typClass1.IsArray || typClass1.IsByRef || typClass1.IsPointer;
protected override bool IsArrayImpl() => typClass1.IsArray;
protected override bool IsByRefImpl() => typClass1.IsByRef;
protected override bool IsCOMObjectImpl() => typClass1.IsCOMObject;
protected override bool IsPointerImpl() => typClass1.IsPointer;
protected override bool IsPrimitiveImpl() => typClass1.IsPrimitive;
}
class Class1
{
private int mlFoo = 0;
public int Foo()
{
return mlFoo;
}
public void SetFoo(int rhs)
{
mlFoo = rhs;
}
}
}
所以我想解决该错误并使我的Type类通过。我应该切换到TypeDelegator class吗?