Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Linq / SequenceQuery.cs / 1305376 / SequenceQuery.cs
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq.Expressions; using System.Reflection; using System.Text; // Include Silverlight's managed resources #if SILVERLIGHT using System.Core; #endif //SILVERLIGHT namespace System.Linq { // Must remain public for Silverlight public abstract class EnumerableQuery { internal abstract Expression Expression { get; } internal abstract IEnumerable Enumerable { get; } internal static IQueryable Create(Type elementType, IEnumerable sequence){ Type seqType = typeof(EnumerableQuery<>).MakeGenericType(elementType); #if SILVERLIGHT return (IQueryable) Activator.CreateInstance(seqType, sequence); #else return (IQueryable) Activator.CreateInstance(seqType, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, new object[] {sequence}, null); #endif //SILVERLIGHT } internal static IQueryable Create(Type elementType, Expression expression) { Type seqType = typeof(EnumerableQuery<>).MakeGenericType(elementType); #if SILVERLIGHT return (IQueryable) Activator.CreateInstance(seqType, expression); #else return (IQueryable) Activator.CreateInstance(seqType, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, new object[] {expression}, null); #endif //SILVERLIGHT } } // Must remain public for Silverlight public class EnumerableQuery: EnumerableQuery, IOrderedQueryable , IQueryable, IQueryProvider, IEnumerable , IEnumerable { Expression expression; IEnumerable enumerable; IQueryProvider IQueryable.Provider { get{ return (IQueryProvider)this; } } // Must remain public for Silverlight public EnumerableQuery(IEnumerable enumerable) { this.enumerable = enumerable; this.expression = Expression.Constant(this); } // Must remain public for Silverlight public EnumerableQuery(Expression expression) { this.expression = expression; } internal override Expression Expression { get { return this.expression; } } internal override IEnumerable Enumerable { get { return this.enumerable; } } Expression IQueryable.Expression { get { return this.expression; } } Type IQueryable.ElementType { get { return typeof(T); } } IQueryable IQueryProvider.CreateQuery(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); Type iqType = TypeHelper.FindGenericType(typeof(IQueryable<>), expression.Type); if (iqType == null) throw Error.ArgumentNotValid("expression"); return EnumerableQuery.Create(iqType.GetGenericArguments()[0], expression); } IQueryable IQueryProvider.CreateQuery(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); if (!typeof(IQueryable).IsAssignableFrom(expression.Type)){ throw Error.ArgumentNotValid("expression"); } return new EnumerableQuery(expression); } // Baselining as Safe for Mix demo so that interface can be transparent. Marking this // critical (which was the original annotation when porting to silverlight) would violate // fxcop security rules if the interface isn't also critical. However, transparent code // can't access this anyway for Mix since we're not exposing AsQueryable(). // [....]: the above assertion no longer holds. Now making AsQueryable() public again // the security fallout of which will need to be re-examined. object IQueryProvider.Execute(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); Type execType = typeof(EnumerableExecutor<>).MakeGenericType(expression.Type); return EnumerableExecutor.Create(expression).ExecuteBoxed(); } // see above S IQueryProvider.Execute(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); if (!typeof(S).IsAssignableFrom(expression.Type)) throw Error.ArgumentNotValid("expression"); return new EnumerableExecutor(expression).Execute(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } IEnumeratorIEnumerable .GetEnumerator() { return this.GetEnumerator(); } IEnumerator GetEnumerator() { if (this.enumerable == null) { EnumerableRewriter rewriter = new EnumerableRewriter(); Expression body = rewriter.Visit(this.expression); Expression >> f = Expression.Lambda >>(body, (IEnumerable )null); this.enumerable = f.Compile()(); } return this.enumerable.GetEnumerator(); } public override string ToString() { ConstantExpression c = this.expression as ConstantExpression; if (c != null && c.Value == this) { if (this.enumerable != null) return this.enumerable.ToString(); return "null"; } return this.expression.ToString(); } } // Must remain public for Silverlight public abstract class EnumerableExecutor { internal abstract object ExecuteBoxed(); internal static EnumerableExecutor Create(Expression expression) { Type execType = typeof(EnumerableExecutor<>).MakeGenericType(expression.Type); #if SILVERLIGHT return (EnumerableExecutor)Activator.CreateInstance(execType, expression); #else return (EnumerableExecutor)Activator.CreateInstance(execType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new object[] { expression }, null); #endif //SILVERLIGHT } } // Must remain public for Silverlight public class EnumerableExecutor : EnumerableExecutor{ Expression expression; Func func; // Must remain public for Silverlight public EnumerableExecutor(Expression expression){ this.expression = expression; } internal override object ExecuteBoxed() { return this.Execute(); } internal T Execute(){ if (this.func == null){ EnumerableRewriter rewriter = new EnumerableRewriter(); Expression body = rewriter.Visit(this.expression); Expression > f = Expression.Lambda >(body, (IEnumerable )null); this.func = f.Compile(); } return this.func(); } } // internal class EnumerableRewriter : OldExpressionVisitor { internal EnumerableRewriter() { } internal override Expression VisitMethodCall(MethodCallExpression m) { Expression obj = this.Visit(m.Object); ReadOnlyCollection args = this.VisitExpressionList(m.Arguments); // check for args changed if (obj != m.Object || args != m.Arguments) { Expression[] argArray = args.ToArray(); Type[] typeArgs = (m.Method.IsGenericMethod) ? m.Method.GetGenericArguments() : null; if ((m.Method.IsStatic || m.Method.DeclaringType.IsAssignableFrom(obj.Type)) && ArgsMatch(m.Method, args, typeArgs)) { // current method is still valid return Expression.Call(obj, m.Method, args); } else if (m.Method.DeclaringType == typeof(Queryable)) { // convert Queryable method to Enumerable method MethodInfo seqMethod = FindEnumerableMethod(m.Method.Name, args, typeArgs); args = this.FixupQuotedArgs(seqMethod, args); return Expression.Call(obj, seqMethod, args); } else { // rebind to new method BindingFlags flags = BindingFlags.Static | (m.Method.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic); MethodInfo method = FindMethod(m.Method.DeclaringType, m.Method.Name, args, typeArgs, flags); args = this.FixupQuotedArgs(method, args); return Expression.Call(obj, method, args); } } return m; } private ReadOnlyCollection FixupQuotedArgs(MethodInfo mi, ReadOnlyCollection argList) { ParameterInfo[] pis = mi.GetParameters(); if (pis.Length > 0) { List newArgs = null; for (int i = 0, n = pis.Length; i < n; i++) { Expression arg = argList[i]; ParameterInfo pi = pis[i]; arg = FixupQuotedExpression(pi.ParameterType, arg); if (newArgs == null && arg != argList[i]) { newArgs = new List (argList.Count); for (int j = 0; j < i; j++) { newArgs.Add(argList[j]); } } if (newArgs != null) { newArgs.Add(arg); } } if (newArgs != null) argList = newArgs.ToReadOnlyCollection(); } return argList; } private Expression FixupQuotedExpression(Type type, Expression expression) { Expression expr = expression; while (true) { if (type.IsAssignableFrom(expr.Type)) return expr; if (expr.NodeType != ExpressionType.Quote) break; expr = ((UnaryExpression)expr).Operand; } if (!type.IsAssignableFrom(expr.Type) && type.IsArray && expr.NodeType == ExpressionType.NewArrayInit) { Type strippedType = StripExpression(expr.Type); if (type.IsAssignableFrom(strippedType)) { Type elementType = type.GetElementType(); NewArrayExpression na = (NewArrayExpression)expr; List exprs = new List (na.Expressions.Count); for (int i = 0, n = na.Expressions.Count; i < n; i++) { exprs.Add(this.FixupQuotedExpression(elementType, na.Expressions[i])); } expression = Expression.NewArrayInit(elementType, exprs); } } return expression; } internal override Expression VisitLambda(LambdaExpression lambda) { return lambda; } private static Type GetPublicType(Type t) { // If we create a constant explicitly typed to be a private nested type, // such as Lookup<,>.Grouping or a compiler-generated iterator class, then // we cannot use the expression tree in a context which has only execution // permissions. We should endeavour to translate constants into // new constants which have public types. if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Lookup<,>.Grouping)) return typeof(IGrouping<,>).MakeGenericType(t.GetGenericArguments()); if (!t.IsNestedPrivate) return t; foreach (Type iType in t.GetInterfaces()) { if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) return iType; } if (typeof(IEnumerable).IsAssignableFrom(t)) return typeof(IEnumerable); return t; } internal override Expression VisitConstant(ConstantExpression c) { EnumerableQuery sq = c.Value as EnumerableQuery; if (sq != null) { if (sq.Enumerable != null) { Type t = GetPublicType(sq.Enumerable.GetType()); return Expression.Constant(sq.Enumerable, t); } return this.Visit(sq.Expression); } return c; } internal override Expression VisitParameter(ParameterExpression p) { return p; } private static ILookup _seqMethods; static MethodInfo FindEnumerableMethod(string name, ReadOnlyCollection args, params Type[] typeArgs) { if (_seqMethods == null) { _seqMethods = typeof(Enumerable).GetMethods(BindingFlags.Static|BindingFlags.Public).ToLookup(m => m.Name); } MethodInfo mi = _seqMethods[name].FirstOrDefault(m => ArgsMatch(m, args, typeArgs)); if (mi == null) throw Error.NoMethodOnTypeMatchingArguments(name, typeof(Enumerable)); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } internal static MethodInfo FindMethod(Type type, string name, ReadOnlyCollection args, Type[] typeArgs, BindingFlags flags) { MethodInfo[] methods = type.GetMethods(flags).Where(m => m.Name == name).ToArray(); if (methods.Length == 0) throw Error.NoMethodOnType(name, type); MethodInfo mi = methods.FirstOrDefault(m => ArgsMatch(m, args, typeArgs)); if (mi == null) throw Error.NoMethodOnTypeMatchingArguments(name, type); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } private static bool ArgsMatch(MethodInfo m, ReadOnlyCollection args, Type[] typeArgs) { ParameterInfo[] mParams = m.GetParameters(); if (mParams.Length != args.Count) return false; if (!m.IsGenericMethod && typeArgs != null && typeArgs.Length > 0) { return false; } if (!m.IsGenericMethodDefinition && m.IsGenericMethod && m.ContainsGenericParameters) { m = m.GetGenericMethodDefinition(); } if (m.IsGenericMethodDefinition) { if (typeArgs == null || typeArgs.Length == 0) return false; if (m.GetGenericArguments().Length != typeArgs.Length) return false; m = m.MakeGenericMethod(typeArgs); mParams = m.GetParameters(); } for (int i = 0, n = args.Count; i < n; i++) { Type parameterType = mParams[i].ParameterType; if (parameterType == null) return false; if (parameterType.IsByRef) parameterType = parameterType.GetElementType(); Expression arg = args[i]; if (!parameterType.IsAssignableFrom(arg.Type)) { if (arg.NodeType == ExpressionType.Quote) { arg = ((UnaryExpression)arg).Operand; } if (!parameterType.IsAssignableFrom(arg.Type) && !parameterType.IsAssignableFrom(StripExpression(arg.Type))) { return false; } } } return true; } private static Type StripExpression(Type type) { bool isArray = type.IsArray; Type tmp = isArray ? type.GetElementType() : type; Type eType = TypeHelper.FindGenericType(typeof(Expression<>), tmp); if (eType != null) tmp = eType.GetGenericArguments()[0]; if (isArray) { int rank = type.GetArrayRank(); return (rank == 1) ? tmp.MakeArrayType() : tmp.MakeArrayType(rank); } return type; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq.Expressions; using System.Reflection; using System.Text; // Include Silverlight's managed resources #if SILVERLIGHT using System.Core; #endif //SILVERLIGHT namespace System.Linq { // Must remain public for Silverlight public abstract class EnumerableQuery { internal abstract Expression Expression { get; } internal abstract IEnumerable Enumerable { get; } internal static IQueryable Create(Type elementType, IEnumerable sequence){ Type seqType = typeof(EnumerableQuery<>).MakeGenericType(elementType); #if SILVERLIGHT return (IQueryable) Activator.CreateInstance(seqType, sequence); #else return (IQueryable) Activator.CreateInstance(seqType, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, new object[] {sequence}, null); #endif //SILVERLIGHT } internal static IQueryable Create(Type elementType, Expression expression) { Type seqType = typeof(EnumerableQuery<>).MakeGenericType(elementType); #if SILVERLIGHT return (IQueryable) Activator.CreateInstance(seqType, expression); #else return (IQueryable) Activator.CreateInstance(seqType, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, new object[] {expression}, null); #endif //SILVERLIGHT } } // Must remain public for Silverlight public class EnumerableQuery : EnumerableQuery, IOrderedQueryable , IQueryable, IQueryProvider, IEnumerable , IEnumerable { Expression expression; IEnumerable enumerable; IQueryProvider IQueryable.Provider { get{ return (IQueryProvider)this; } } // Must remain public for Silverlight public EnumerableQuery(IEnumerable enumerable) { this.enumerable = enumerable; this.expression = Expression.Constant(this); } // Must remain public for Silverlight public EnumerableQuery(Expression expression) { this.expression = expression; } internal override Expression Expression { get { return this.expression; } } internal override IEnumerable Enumerable { get { return this.enumerable; } } Expression IQueryable.Expression { get { return this.expression; } } Type IQueryable.ElementType { get { return typeof(T); } } IQueryable IQueryProvider.CreateQuery(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); Type iqType = TypeHelper.FindGenericType(typeof(IQueryable<>), expression.Type); if (iqType == null) throw Error.ArgumentNotValid("expression"); return EnumerableQuery.Create(iqType.GetGenericArguments()[0], expression); } IQueryable IQueryProvider.CreateQuery(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); if (!typeof(IQueryable).IsAssignableFrom(expression.Type)){ throw Error.ArgumentNotValid("expression"); } return new EnumerableQuery(expression); } // Baselining as Safe for Mix demo so that interface can be transparent. Marking this // critical (which was the original annotation when porting to silverlight) would violate // fxcop security rules if the interface isn't also critical. However, transparent code // can't access this anyway for Mix since we're not exposing AsQueryable(). // [....]: the above assertion no longer holds. Now making AsQueryable() public again // the security fallout of which will need to be re-examined. object IQueryProvider.Execute(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); Type execType = typeof(EnumerableExecutor<>).MakeGenericType(expression.Type); return EnumerableExecutor.Create(expression).ExecuteBoxed(); } // see above S IQueryProvider.Execute(Expression expression){ if (expression == null) throw Error.ArgumentNull("expression"); if (!typeof(S).IsAssignableFrom(expression.Type)) throw Error.ArgumentNotValid("expression"); return new EnumerableExecutor(expression).Execute(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } IEnumeratorIEnumerable .GetEnumerator() { return this.GetEnumerator(); } IEnumerator GetEnumerator() { if (this.enumerable == null) { EnumerableRewriter rewriter = new EnumerableRewriter(); Expression body = rewriter.Visit(this.expression); Expression >> f = Expression.Lambda >>(body, (IEnumerable )null); this.enumerable = f.Compile()(); } return this.enumerable.GetEnumerator(); } public override string ToString() { ConstantExpression c = this.expression as ConstantExpression; if (c != null && c.Value == this) { if (this.enumerable != null) return this.enumerable.ToString(); return "null"; } return this.expression.ToString(); } } // Must remain public for Silverlight public abstract class EnumerableExecutor { internal abstract object ExecuteBoxed(); internal static EnumerableExecutor Create(Expression expression) { Type execType = typeof(EnumerableExecutor<>).MakeGenericType(expression.Type); #if SILVERLIGHT return (EnumerableExecutor)Activator.CreateInstance(execType, expression); #else return (EnumerableExecutor)Activator.CreateInstance(execType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new object[] { expression }, null); #endif //SILVERLIGHT } } // Must remain public for Silverlight public class EnumerableExecutor : EnumerableExecutor{ Expression expression; Func func; // Must remain public for Silverlight public EnumerableExecutor(Expression expression){ this.expression = expression; } internal override object ExecuteBoxed() { return this.Execute(); } internal T Execute(){ if (this.func == null){ EnumerableRewriter rewriter = new EnumerableRewriter(); Expression body = rewriter.Visit(this.expression); Expression > f = Expression.Lambda >(body, (IEnumerable )null); this.func = f.Compile(); } return this.func(); } } // internal class EnumerableRewriter : OldExpressionVisitor { internal EnumerableRewriter() { } internal override Expression VisitMethodCall(MethodCallExpression m) { Expression obj = this.Visit(m.Object); ReadOnlyCollection args = this.VisitExpressionList(m.Arguments); // check for args changed if (obj != m.Object || args != m.Arguments) { Expression[] argArray = args.ToArray(); Type[] typeArgs = (m.Method.IsGenericMethod) ? m.Method.GetGenericArguments() : null; if ((m.Method.IsStatic || m.Method.DeclaringType.IsAssignableFrom(obj.Type)) && ArgsMatch(m.Method, args, typeArgs)) { // current method is still valid return Expression.Call(obj, m.Method, args); } else if (m.Method.DeclaringType == typeof(Queryable)) { // convert Queryable method to Enumerable method MethodInfo seqMethod = FindEnumerableMethod(m.Method.Name, args, typeArgs); args = this.FixupQuotedArgs(seqMethod, args); return Expression.Call(obj, seqMethod, args); } else { // rebind to new method BindingFlags flags = BindingFlags.Static | (m.Method.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic); MethodInfo method = FindMethod(m.Method.DeclaringType, m.Method.Name, args, typeArgs, flags); args = this.FixupQuotedArgs(method, args); return Expression.Call(obj, method, args); } } return m; } private ReadOnlyCollection FixupQuotedArgs(MethodInfo mi, ReadOnlyCollection argList) { ParameterInfo[] pis = mi.GetParameters(); if (pis.Length > 0) { List newArgs = null; for (int i = 0, n = pis.Length; i < n; i++) { Expression arg = argList[i]; ParameterInfo pi = pis[i]; arg = FixupQuotedExpression(pi.ParameterType, arg); if (newArgs == null && arg != argList[i]) { newArgs = new List (argList.Count); for (int j = 0; j < i; j++) { newArgs.Add(argList[j]); } } if (newArgs != null) { newArgs.Add(arg); } } if (newArgs != null) argList = newArgs.ToReadOnlyCollection(); } return argList; } private Expression FixupQuotedExpression(Type type, Expression expression) { Expression expr = expression; while (true) { if (type.IsAssignableFrom(expr.Type)) return expr; if (expr.NodeType != ExpressionType.Quote) break; expr = ((UnaryExpression)expr).Operand; } if (!type.IsAssignableFrom(expr.Type) && type.IsArray && expr.NodeType == ExpressionType.NewArrayInit) { Type strippedType = StripExpression(expr.Type); if (type.IsAssignableFrom(strippedType)) { Type elementType = type.GetElementType(); NewArrayExpression na = (NewArrayExpression)expr; List exprs = new List (na.Expressions.Count); for (int i = 0, n = na.Expressions.Count; i < n; i++) { exprs.Add(this.FixupQuotedExpression(elementType, na.Expressions[i])); } expression = Expression.NewArrayInit(elementType, exprs); } } return expression; } internal override Expression VisitLambda(LambdaExpression lambda) { return lambda; } private static Type GetPublicType(Type t) { // If we create a constant explicitly typed to be a private nested type, // such as Lookup<,>.Grouping or a compiler-generated iterator class, then // we cannot use the expression tree in a context which has only execution // permissions. We should endeavour to translate constants into // new constants which have public types. if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Lookup<,>.Grouping)) return typeof(IGrouping<,>).MakeGenericType(t.GetGenericArguments()); if (!t.IsNestedPrivate) return t; foreach (Type iType in t.GetInterfaces()) { if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) return iType; } if (typeof(IEnumerable).IsAssignableFrom(t)) return typeof(IEnumerable); return t; } internal override Expression VisitConstant(ConstantExpression c) { EnumerableQuery sq = c.Value as EnumerableQuery; if (sq != null) { if (sq.Enumerable != null) { Type t = GetPublicType(sq.Enumerable.GetType()); return Expression.Constant(sq.Enumerable, t); } return this.Visit(sq.Expression); } return c; } internal override Expression VisitParameter(ParameterExpression p) { return p; } private static ILookup _seqMethods; static MethodInfo FindEnumerableMethod(string name, ReadOnlyCollection args, params Type[] typeArgs) { if (_seqMethods == null) { _seqMethods = typeof(Enumerable).GetMethods(BindingFlags.Static|BindingFlags.Public).ToLookup(m => m.Name); } MethodInfo mi = _seqMethods[name].FirstOrDefault(m => ArgsMatch(m, args, typeArgs)); if (mi == null) throw Error.NoMethodOnTypeMatchingArguments(name, typeof(Enumerable)); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } internal static MethodInfo FindMethod(Type type, string name, ReadOnlyCollection args, Type[] typeArgs, BindingFlags flags) { MethodInfo[] methods = type.GetMethods(flags).Where(m => m.Name == name).ToArray(); if (methods.Length == 0) throw Error.NoMethodOnType(name, type); MethodInfo mi = methods.FirstOrDefault(m => ArgsMatch(m, args, typeArgs)); if (mi == null) throw Error.NoMethodOnTypeMatchingArguments(name, type); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } private static bool ArgsMatch(MethodInfo m, ReadOnlyCollection args, Type[] typeArgs) { ParameterInfo[] mParams = m.GetParameters(); if (mParams.Length != args.Count) return false; if (!m.IsGenericMethod && typeArgs != null && typeArgs.Length > 0) { return false; } if (!m.IsGenericMethodDefinition && m.IsGenericMethod && m.ContainsGenericParameters) { m = m.GetGenericMethodDefinition(); } if (m.IsGenericMethodDefinition) { if (typeArgs == null || typeArgs.Length == 0) return false; if (m.GetGenericArguments().Length != typeArgs.Length) return false; m = m.MakeGenericMethod(typeArgs); mParams = m.GetParameters(); } for (int i = 0, n = args.Count; i < n; i++) { Type parameterType = mParams[i].ParameterType; if (parameterType == null) return false; if (parameterType.IsByRef) parameterType = parameterType.GetElementType(); Expression arg = args[i]; if (!parameterType.IsAssignableFrom(arg.Type)) { if (arg.NodeType == ExpressionType.Quote) { arg = ((UnaryExpression)arg).Operand; } if (!parameterType.IsAssignableFrom(arg.Type) && !parameterType.IsAssignableFrom(StripExpression(arg.Type))) { return false; } } } return true; } private static Type StripExpression(Type type) { bool isArray = type.IsArray; Type tmp = isArray ? type.GetElementType() : type; Type eType = TypeHelper.FindGenericType(typeof(Expression<>), tmp); if (eType != null) tmp = eType.GetGenericArguments()[0]; if (isArray) { int rank = type.GetArrayRank(); return (rank == 1) ? tmp.MakeArrayType() : tmp.MakeArrayType(rank); } return type; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- UniformGrid.cs
- TimeSpanValidator.cs
- FileIOPermission.cs
- DynamicAttribute.cs
- typedescriptorpermission.cs
- BindingExpression.cs
- BasicCellRelation.cs
- Decimal.cs
- AnimationTimeline.cs
- Variant.cs
- ConfigXmlAttribute.cs
- ButtonStandardAdapter.cs
- TextSegment.cs
- WindowsGraphics2.cs
- SafeTokenHandle.cs
- MouseEvent.cs
- PropertyMap.cs
- ServiceContractViewControl.Designer.cs
- WinEventHandler.cs
- DateTimeStorage.cs
- ParameterModifier.cs
- SqlWebEventProvider.cs
- ExportOptions.cs
- StateManagedCollection.cs
- DefaultSection.cs
- XmlAnyAttributeAttribute.cs
- ReadOnlyCollection.cs
- PriorityQueue.cs
- ToolStripPanelRow.cs
- UrlPath.cs
- XamlToRtfParser.cs
- EventSinkHelperWriter.cs
- Convert.cs
- XmlLanguageConverter.cs
- SerializationSectionGroup.cs
- ConnectionStringSettings.cs
- UnsafeNativeMethods.cs
- SecureEnvironment.cs
- TrustSection.cs
- ipaddressinformationcollection.cs
- CategoryNameCollection.cs
- BitArray.cs
- PeerNameRecordCollection.cs
- SQLSingleStorage.cs
- XmlAggregates.cs
- MetadataWorkspace.cs
- AnonymousIdentificationSection.cs
- MulticastOption.cs
- XPathSingletonIterator.cs
- ElapsedEventArgs.cs
- WebPartHelpVerb.cs
- TemplateKeyConverter.cs
- Line.cs
- Gdiplus.cs
- Pair.cs
- X509WindowsSecurityToken.cs
- ColorTranslator.cs
- QilParameter.cs
- DbFunctionCommandTree.cs
- StringValidatorAttribute.cs
- DataGridItem.cs
- GridItemProviderWrapper.cs
- SecurityTokenReferenceStyle.cs
- CharKeyFrameCollection.cs
- NumberFunctions.cs
- SizeFConverter.cs
- HtmlEmptyTagControlBuilder.cs
- Rules.cs
- BinaryConverter.cs
- HealthMonitoringSection.cs
- PickBranchDesigner.xaml.cs
- Context.cs
- TextElementEditingBehaviorAttribute.cs
- CngAlgorithm.cs
- TextElementEditingBehaviorAttribute.cs
- EdmMember.cs
- ForeignConstraint.cs
- SafeViewOfFileHandle.cs
- CounterCreationDataConverter.cs
- GPPOINTF.cs
- SharedStatics.cs
- RepeaterItemEventArgs.cs
- localization.cs
- LeaseManager.cs
- BaseParagraph.cs
- WebPartEventArgs.cs
- LinkButton.cs
- ComboBox.cs
- ToolStripComboBox.cs
- IncomingWebResponseContext.cs
- EntityViewGenerator.cs
- SqlClientMetaDataCollectionNames.cs
- OracleCommandSet.cs
- EncryptedType.cs
- Separator.cs
- TrackingExtract.cs
- TransformerInfoCollection.cs
- CompilationSection.cs
- WindowHideOrCloseTracker.cs
- TextServicesPropertyRanges.cs