├── .vs ├── Fasterflect │ └── v14 │ │ └── .suo └── restore.dg ├── MyGet.bat ├── src └── Fasterflect.Netstandard │ ├── Emitter │ ├── EmitHelper.cs │ ├── ValueTypeHolder.cs │ ├── ArrayGetEmitter.cs │ ├── ArraySetEmitter.cs │ ├── InvocationEmitter.cs │ ├── MapCallInfo.cs │ ├── BaseEmitter.cs │ ├── CtorInvocationEmitter.cs │ ├── MemberSetEmitter.cs │ ├── MemberGetEmitter.cs │ ├── MethodInvocationEmitter.cs │ └── MapEmitter.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Extensions │ ├── Net35CompatibilityExtensions.cs │ ├── Core │ │ ├── ConstructorInfoExtensions.cs │ │ ├── ArrayExtensions.cs │ │ ├── ValueTypeExtensions.cs │ │ ├── FieldInfoExtensions.cs │ │ ├── ParameterInfoExtensions.cs │ │ ├── PropertyInfoExtensions.cs │ │ ├── AssemblyExtensions.cs │ │ └── MethodInfoExtensions.cs │ └── Services │ │ ├── Probing │ │ └── ConstructorMap.cs │ │ ├── TryCallMethodExtensions.cs │ │ └── XmlTransformerExtensions.cs │ ├── Caching │ └── CacheStrategy.cs │ ├── Common │ ├── Constants.cs │ ├── FormatOptions.cs │ ├── Utils.cs │ └── Delegates.cs │ ├── Fasterflect.Netstandard.csproj │ └── DynamicReflection │ ├── DynamicBuilder.cs │ └── DynamicWrapper.cs ├── .hgignore ├── tests └── Fasterflect.Netframework.Tests │ ├── packages.config │ ├── Properties │ └── AssemblyInfo.cs │ ├── SampleModel │ ├── Generics │ │ ├── Concrete.cs │ │ ├── GenericBase.cs │ │ └── AbstractGenericBase.cs │ ├── People │ │ ├── ISwimmable.cs │ │ ├── Employee.cs │ │ ├── Person.cs │ │ └── PersonStruct.cs │ └── Animals │ │ ├── Interfaces │ │ ├── IBite.cs │ │ ├── ISlide.cs │ │ └── ISwim.cs │ │ ├── Attributes │ │ ├── CarnivoreAttribute.cs │ │ ├── CodeAttribute.cs │ │ └── ZoneAttribute.cs │ │ ├── Enumerations │ │ ├── MovementCapabilities.cs │ │ ├── Zone.cs │ │ └── Climate.cs │ │ ├── Mammal.cs │ │ ├── Reptile.cs │ │ ├── Giraffe.cs │ │ ├── Zoo.cs │ │ ├── Snake.cs │ │ ├── Elephant.cs │ │ ├── Animal.cs │ │ └── Lion.cs │ ├── Issues │ ├── IssueList.cs │ ├── AmbiguousMatchTest.cs │ └── IssueList2.cs │ ├── Invocation │ ├── TestUtils.cs │ ├── BaseInvocationTest.cs │ ├── MemberTest.cs │ ├── ArrayTest.cs │ ├── IndexerTest.cs │ ├── GenericTest.cs │ ├── DelegateCacheTest.cs │ └── DelegateTest.cs │ ├── Common │ ├── TestUtils.cs │ └── BaseTest.cs │ ├── Internal │ └── FlagsTest.cs │ ├── Services │ ├── DynamicTest.cs │ ├── XmlTransformerTest.cs │ └── EventHandlerTest.cs │ ├── Lookup │ ├── AssemblyTest.cs │ ├── TryGetSetTest.cs │ ├── ParameterTest.cs │ └── ConstructorTest.cs │ └── Probing │ ├── TryCallMethodTest.cs │ ├── TypeConverterTest.cs │ ├── TryCallMethodValuesOnlyTest.cs │ └── MethodDispatcherTest.cs ├── NuGet.config ├── post-MyGet.ps1 └── Fasterflect.sln /.vs/Fasterflect/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloKitty/fasterflect/HEAD/.vs/Fasterflect/v14/.suo -------------------------------------------------------------------------------- /MyGet.bat: -------------------------------------------------------------------------------- 1 | %NUGET% restore Fasterflect.sln -NoCache -NonInteractive 2 | msbuild Fasterflect.sln /p:Configuration=Release -------------------------------------------------------------------------------- /.vs/restore.dg: -------------------------------------------------------------------------------- 1 | #:C:\Users\Glader\Documents\GitHub\fasterflect\src\Fasterflect.Netstandard\Fasterflect.Netstandard.xproj 2 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/EmitHelper.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloKitty/fasterflect/HEAD/src/Fasterflect.Netstandard/Emitter/EmitHelper.cs -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.ReSharper 3 | *.user 4 | bin 5 | obj 6 | Output 7 | Nuget/packages 8 | Nuget/fasterflect.* 9 | *.suo 10 | *.vs10x 11 | *.DotSettings 12 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /post-MyGet.ps1: -------------------------------------------------------------------------------- 1 | ##Looks through the entire src directory and runs nuget pack with dependencies added on each csproj found 2 | ##foreach file in src/* 3 | foreach($f in Get-ChildItem ./src/) 4 | { 5 | ##foreach file in the src/*/ directory that ends with the .csproj format 6 | foreach($ff in (Get-ChildItem (Join-Path ./src/ $f.Name) | Where-Object { $_.Name.EndsWith(".csproj") })) 7 | { 8 | ##Add the project path + the csproj name and add the include referenced projects argument which will 9 | ##force nuget dependencies 10 | $projectArgs = "pack " + (Join-Path (Join-Path src/ $f.Name) $ff.Name)## + " -IncludeReferencedProjects" 11 | Start-Process dotnet $projectArgs -Wait 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("Fasterflect.Netframework.Tests")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("Microsoft")] 9 | [assembly: AssemblyProduct("Fasterflect.Netframework.Tests")] 10 | [assembly: AssemblyCopyright("Copyright © Microsoft 2017")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | [assembly: ComVisible(false)] 15 | 16 | [assembly: Guid("4ef5f3a5-53af-4291-aba0-0dd6dcb2e89b")] 17 | 18 | // [assembly: AssemblyVersion("1.0.*")] 19 | [assembly: AssemblyVersion("1.0.0.0")] 20 | [assembly: AssemblyFileVersion("1.0.0.0")] 21 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Generics/Concrete.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.SampleModel.Generics 22 | { 23 | internal class Concrete : GenericBase 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Generics/GenericBase.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.SampleModel.Generics 22 | { 23 | internal class GenericBase : AbstractGenericBase 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/People/ISwimmable.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.SampleModel.People 22 | { 23 | public interface ISwimmable 24 | { 25 | void Swim( double meters ); 26 | } 27 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("www.github.com/hellokitty")] 10 | [assembly: AssemblyProduct("Fasterflect")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: InternalsVisibleTo("Fasterflect.Netframework.Tests")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("5c6966b7-610e-42d2-9661-c80c46392124")] 21 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Interfaces/IBite.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | 23 | namespace FasterflectTest.SampleModel.Animals.Interfaces 24 | { 25 | internal interface IBite 26 | { 27 | bool Bite( Animal animal ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Generics/AbstractGenericBase.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.SampleModel.Generics 22 | { 23 | internal abstract class AbstractGenericBase 24 | { 25 | public virtual T Value { get; protected set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Interfaces/ISlide.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.SampleModel.Animals.Interfaces 22 | { 23 | internal interface ISlide 24 | { 25 | double SlideDistance { get; } 26 | 27 | void Move( double distance ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Interfaces/ISwim.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | 23 | namespace FasterflectTest.SampleModel.Animals.Interfaces 24 | { 25 | internal interface ISwim 26 | { 27 | double SwimDistance { get; } 28 | 29 | void Move( double distance ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Attributes/CarnivoreAttribute.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | 23 | namespace FasterflectTest.SampleModel.Animals.Attributes 24 | { 25 | [AttributeUsage(AttributeTargets.Class)] 26 | internal class CarnivoreAttribute : Attribute 27 | { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Issues/IssueList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using Fasterflect; 4 | using NUnit.Framework; 5 | 6 | namespace FasterflectTest.Issues 7 | { 8 | [TestFixture] 9 | public class IssueList 10 | { 11 | [Test] 12 | public void Issue1() 13 | { 14 | Console.WriteLine("List 1: Add() without Fasterflect"); 15 | var list1 = (ArrayList)typeof(ArrayList).CreateInstance(); 16 | for (int i = 0; i < 10; i++) 17 | { 18 | list1.Add( i ); 19 | } 20 | 21 | Console.WriteLine("List 1: Add() by Fasterflect"); 22 | var list2 = typeof(ArrayList).CreateInstance(); 23 | for (int i = 0; i < 10; i++) 24 | { 25 | list2.CallMethod("Add", i); 26 | } 27 | //var size = (int)list2.GetPropertyValue("Count"); 28 | //for (int i = 0; i < size; i++) 29 | //{ 30 | // Assert.AreEqual(i + 1, list2.GetIndexer(i)); 31 | //} 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Enumerations/MovementCapabilities.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | 23 | namespace FasterflectTest.SampleModel.Animals.Enumerations 24 | { 25 | [Flags] 26 | internal enum MovementCapabilities 27 | { 28 | Land = 1, 29 | Water = 2, 30 | Air = 4 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Enumerations/Zone.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | 23 | namespace FasterflectTest.SampleModel.Animals.Enumerations 24 | { 25 | [Flags] 26 | internal enum Zone 27 | { 28 | Arctic = 1, 29 | Ocean = 1 << 1, 30 | Savannah = 1 << 2, 31 | Jungle = 1 << 3, 32 | Plains = 1 << 4, 33 | Woods = 1 << 5, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Net35CompatibilityExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace Fasterflect 7 | { 8 | /// 9 | /// Extensions class that help make net46 and netstandard code 10 | /// compatible with net35 without conditional compilation everywhere. 11 | /// 12 | public static class Net35CompatibilityExtensions 13 | { 14 | #if NET35 15 | /// 16 | /// A net35 extension that fills out GetTypeInfo for net35. 17 | /// 18 | /// 19 | /// Just the provided type. 20 | public static Type GetTypeInfo(this Type t) 21 | { 22 | return t; 23 | } 24 | 25 | /// 26 | /// A net35 extension that fills out GetMethodInfo for net35 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | public static MethodInfo GetMethodInfo(this Func func) 33 | { 34 | return func.Method; 35 | } 36 | #endif 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Attributes/CodeAttribute.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | 23 | namespace FasterflectTest.SampleModel.Animals.Attributes 24 | { 25 | [AttributeUsage(AttributeTargets.All)] 26 | internal class CodeAttribute : Attribute 27 | { 28 | public string Code { get; set; } 29 | 30 | public CodeAttribute( string code ) 31 | { 32 | Code = code; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Enumerations/Climate.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using FasterflectTest.SampleModel.Animals.Attributes; 23 | 24 | namespace FasterflectTest.SampleModel.Animals.Enumerations 25 | { 26 | [Flags] 27 | [Code("Temperature")] 28 | internal enum Climate 29 | { 30 | [Code("Hot")] 31 | Hot = 1, 32 | [Code("Cold")] 33 | Cold = 2, 34 | [Code("Any")] 35 | Any = Hot | Cold 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Issues/AmbiguousMatchTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Linq; 4 | using Fasterflect; 5 | using NUnit.Framework; 6 | 7 | namespace FasterflectTest.Issues 8 | { 9 | [TestFixture] 10 | public class AmbiguousMatchTest 11 | { 12 | #region Sample Classes 13 | private class Foo 14 | { 15 | public object Property { get; set; } 16 | } 17 | private class Bar : Foo 18 | { 19 | public new string Property { get; set; } 20 | } 21 | #endregion 22 | 23 | [Test] 24 | public void Test_PropertyLookupWithNameAndEXHFlagShouldNotThrowAmbiguousMatchException() 25 | { 26 | var propertyInfo = typeof(Bar).Property( "Property", Flags.InstanceAnyVisibility | Flags.ExcludeHiddenMembers ); 27 | Assert.IsNotNull( propertyInfo ); 28 | Assert.AreEqual( typeof(Bar), propertyInfo.DeclaringType ); 29 | } 30 | 31 | [Test] 32 | public void Test_PropertiesLookupWithNameAndEXHFlagShouldFindSingleResult() 33 | { 34 | var propertyInfo = typeof(Bar).Properties( Flags.InstanceAnyVisibility | Flags.ExcludeHiddenMembers, "Property" ).Single(); 35 | Assert.IsNotNull( propertyInfo ); 36 | Assert.AreEqual( typeof(Bar), propertyInfo.DeclaringType ); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/TestUtils.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.Invocation 22 | { 23 | public static class TestUtils 24 | { 25 | public static string FirstCharUpper( this string str ) 26 | { 27 | if( string.IsNullOrEmpty( str ) ) 28 | { 29 | return str; 30 | } 31 | return str.Substring( 0, 1 ).ToUpper() + str.Substring( 1 ); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Attributes/ZoneAttribute.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using FasterflectTest.SampleModel.Animals.Enumerations; 23 | 24 | namespace FasterflectTest.SampleModel.Animals.Attributes 25 | { 26 | [AttributeUsage(AttributeTargets.Class)] 27 | internal class ZoneAttribute : Attribute 28 | { 29 | public Zone Zone { get; set; } 30 | 31 | public ZoneAttribute( Zone zone ) 32 | { 33 | Zone = zone; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Mammal.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using FasterflectTest.SampleModel.Animals.Enumerations; 22 | 23 | namespace FasterflectTest.SampleModel.Animals 24 | { 25 | internal abstract class Mammal : Animal 26 | { 27 | protected Mammal( Climate climateRequirements, MovementCapabilities movementCapabilities ) : base( climateRequirements, movementCapabilities ) 28 | { 29 | } 30 | 31 | protected Mammal( int id, Climate climateRequirements, MovementCapabilities movementCapabilities ) : base( id, climateRequirements, movementCapabilities ) 32 | { 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Common/TestUtils.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.Common 22 | { 23 | public static class TestUtils 24 | { 25 | public static string FirstCharUpper( this string str ) 26 | { 27 | if( string.IsNullOrEmpty( str ) ) 28 | { 29 | return str; 30 | } 31 | return str.Substring( 0, 1 ).ToUpper() + str.Substring( 1 ); 32 | } 33 | 34 | public static string FirstCharLower( this string str ) 35 | { 36 | if( string.IsNullOrEmpty( str ) ) 37 | { 38 | return str; 39 | } 40 | return str.Substring( 0, 1 ).ToLower() + str.Substring( 1 ); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Reptile.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using FasterflectTest.SampleModel.Animals.Enumerations; 22 | using FasterflectTest.SampleModel.Animals.Interfaces; 23 | 24 | namespace FasterflectTest.SampleModel.Animals 25 | { 26 | internal abstract class Reptile : Animal, ISlide 27 | { 28 | protected Reptile( Climate climateRequirements, MovementCapabilities movementCapabilities ) : base( climateRequirements, movementCapabilities ) 29 | { 30 | } 31 | 32 | protected Reptile( int id, Climate climateRequirements, MovementCapabilities movementCapabilities ) : base( id, climateRequirements, movementCapabilities ) 33 | { 34 | } 35 | 36 | public virtual double SlideDistance { get; protected set; } 37 | 38 | public abstract void Move( double distance ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/BaseInvocationTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using FasterflectTest.Common; 23 | using FasterflectTest.SampleModel.People; 24 | 25 | namespace FasterflectTest.Invocation 26 | { 27 | public abstract class BaseInvocationTest : BaseTest 28 | { 29 | protected static readonly Type EmployeeType = typeof(Employee); 30 | protected static readonly Type PersonType = typeof(Person); 31 | protected static readonly Type PersonStructType = typeof(PersonStruct); 32 | 33 | protected BaseInvocationTest() : base( new [] { PersonType, PersonStructType } ) 34 | { 35 | } 36 | 37 | protected BaseInvocationTest(Type classType, Type structType) 38 | : base(new []{classType, structType}) 39 | { 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Internal/FlagsTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using Fasterflect; 22 | using NUnit.Framework; 23 | 24 | namespace FasterflectTest.Internal 25 | { 26 | [TestFixture] 27 | public class FlagsTest 28 | { 29 | [Test] 30 | public void TestFlagsToString() 31 | { 32 | Assert.AreEqual( string.Empty, Flags.None.ToString() ); 33 | Assert.AreEqual( "Public", Flags.Public.ToString() ); 34 | Assert.AreEqual( "Instance", Flags.Instance.ToString() ); 35 | Assert.AreEqual( "Public", (Flags.None | Flags.Public).ToString() ); 36 | Assert.AreEqual( "Instance | Public", (Flags.Instance | Flags.Public).ToString() ); 37 | Assert.AreEqual( "Instance | NonPublic | Public", (Flags.Instance | Flags.Public | Flags.NonPublic).ToString() ); 38 | Assert.AreEqual( "Instance | NonPublic | Public", Flags.InstanceAnyVisibility.ToString() ); 39 | } 40 | } 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Caching/CacheStrategy.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace Fasterflect.Caching 22 | { 23 | /// 24 | /// An enumeration of the supported caching strategies. 25 | /// 26 | internal enum CacheStrategy 27 | { 28 | /// 29 | /// This value indicates that caching is disabled. 30 | /// 31 | None, 32 | /// 33 | /// This value indicates that caching is enabled, and that cached objects may be 34 | /// collected and released at will by the garbage collector. This is the default value. 35 | /// 36 | Temporary, 37 | /// 38 | /// This value indicates that caching is enabled, and that cached objects may not 39 | /// be garbage collected. The developer must manually ensure that objects are 40 | /// removed from the cache when they are no longer needed. 41 | /// 42 | Permanent 43 | } 44 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/ValueTypeHolder.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | 21 | namespace Fasterflect.Emitter 22 | { 23 | /// 24 | /// A wrapper for value type. Must be used in order for Fasterflect to 25 | /// work with value type such as struct. 26 | /// 27 | internal class ValueTypeHolder 28 | { 29 | /// 30 | /// Creates a wrapper for value type. The wrapper 31 | /// can then be used with Fasterflect. 32 | /// 33 | /// The value type to be wrapped. 34 | /// Must be a derivative of ValueType. 35 | public ValueTypeHolder( object value ) 36 | { 37 | Value = (ValueType) value; 38 | } 39 | 40 | /// 41 | /// The actual struct wrapped by this instance. 42 | /// 43 | public ValueType Value { get; set; } 44 | } 45 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/People/Employee.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | namespace FasterflectTest.SampleModel.People 22 | { 23 | public class Employee : Person, ISwimmable 24 | { 25 | private int employeeId; 26 | 27 | public int EmployeeId 28 | { 29 | get { return employeeId; } 30 | set { employeeId = value; } 31 | } 32 | 33 | public Employee[] Subordinates { get; private set; } 34 | 35 | public Employee( string name, int age ) : base( name, age ) 36 | { 37 | employeeId = GetTotalPeopleCreated(); 38 | } 39 | 40 | public Employee() : this( string.Empty, 0 ) 41 | { 42 | } 43 | 44 | public Employee( Employee[] subordinates ) : this( string.Empty, 0 ) 45 | { 46 | Subordinates = subordinates; 47 | } 48 | 49 | void ISwimmable.Swim( double meters ) 50 | { 51 | metersTravelled += meters; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Giraffe.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using FasterflectTest.SampleModel.Animals.Attributes; 22 | using FasterflectTest.SampleModel.Animals.Enumerations; 23 | using FasterflectTest.SampleModel.Animals.Interfaces; 24 | 25 | namespace FasterflectTest.SampleModel.Animals 26 | { 27 | [Zone(Zone.Savannah)] 28 | internal class Giraffe : Mammal, ISwim 29 | { 30 | public Giraffe( int id, Climate climateRequirements, MovementCapabilities movementCapabilities ) : base( id, climateRequirements, movementCapabilities ) 31 | { 32 | } 33 | 34 | public Giraffe( Climate climateRequirements, MovementCapabilities movementCapabilities ) : base( climateRequirements, movementCapabilities ) 35 | { 36 | } 37 | 38 | #region ISwim Members 39 | double ISwim.SwimDistance 40 | { 41 | get { throw new System.NotImplementedException(); } 42 | } 43 | 44 | void ISwim.Move( double distance ) 45 | { 46 | throw new System.NotImplementedException(); 47 | } 48 | #endregion 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Zoo.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System.Collections.Generic; 22 | using System.Collections.ObjectModel; 23 | using System.Linq; 24 | 25 | namespace FasterflectTest.SampleModel.Animals 26 | { 27 | internal sealed class Zoo : Collection 28 | { 29 | private const int FirstId = 1000; 30 | private static int nextId = FirstId; 31 | private readonly string name; 32 | private string alias; 33 | 34 | public Zoo( string name ) 35 | { 36 | this.name = name; 37 | alias = name; 38 | } 39 | 40 | public IEnumerable Animals() 41 | { 42 | return this.Where( a => a is T ).Cast(); 43 | } 44 | 45 | public void RegisterClass( string @class, string _section, string __name, int size ) 46 | { 47 | } 48 | 49 | public string Name 50 | { 51 | get { return name; } 52 | } 53 | public string Alias 54 | { 55 | set { alias = value; } 56 | } 57 | 58 | public static int NextId 59 | { 60 | get { return ++nextId; } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Snake.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.ComponentModel; 23 | using FasterflectTest.SampleModel.Animals.Enumerations; 24 | using FasterflectTest.SampleModel.Animals.Interfaces; 25 | 26 | namespace FasterflectTest.SampleModel.Animals 27 | { 28 | internal class Snake : Reptile, ISwim, IBite 29 | { 30 | public Snake() : base( Climate.Hot, MovementCapabilities.Land ) 31 | { 32 | HasDeadlyBite = true; 33 | } 34 | 35 | // regular member 36 | public bool HasDeadlyBite { get; private set; } 37 | 38 | // ISwim 39 | void ISwim.Move( double distance ) 40 | { 41 | SwimDistance += distance; 42 | } 43 | public virtual double SwimDistance { get; private set; } 44 | 45 | // ISlide 46 | public override void Move( [DefaultValue(100d)] double distance ) 47 | { 48 | SlideDistance += distance; 49 | } 50 | public override double SlideDistance { get; protected set; } 51 | 52 | // IBite 53 | public bool Bite( Animal animal ) 54 | { 55 | return HasDeadlyBite; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Common/Constants.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Reflection; 23 | using Fasterflect.Emitter; 24 | 25 | namespace Fasterflect 26 | { 27 | internal static class Constants 28 | { 29 | public const string IndexerSetterName = "set_Item"; 30 | public const string IndexerGetterName = "get_Item"; 31 | public const string ArraySetterName = "[]="; 32 | public const string ArrayGetterName = "=[]"; 33 | public static readonly Type ObjectType = typeof(object); 34 | public static readonly Type IntType = typeof(int); 35 | public static readonly Type StructType = typeof(ValueTypeHolder); 36 | public static readonly Type VoidType = typeof(void); 37 | public static readonly Type[] ArrayOfObjectType = new[] { typeof(object) }; 38 | public static readonly object[] EmptyObjectArray = new object[0]; 39 | public static readonly string[] EmptyStringArray = new string[0]; 40 | public static readonly PropertyInfo[] EmptyPropertyInfoArray = new PropertyInfo[0]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/MemberTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using Fasterflect; 23 | using NUnit.Framework; 24 | 25 | namespace FasterflectTest.Invocation 26 | { 27 | [TestFixture] 28 | public class MemberTest : BaseInvocationTest 29 | { 30 | [Test] 31 | public void TestAccessStaticMemberViaMemberInfo() 32 | { 33 | RunWith((Type type) => 34 | { 35 | var memberInfo = type.Member("TotalPeopleCreated", Flags.StaticAnyVisibility); 36 | var totalPeopleCreated = (int)memberInfo.Get() + 1; 37 | memberInfo.Set(totalPeopleCreated); 38 | VerifyProperties(type, new { totalPeopleCreated }); 39 | }); 40 | } 41 | 42 | [Test] 43 | public void TestAccessInstanceMemberViaMemberInfo() 44 | { 45 | RunWith((object person) => 46 | { 47 | var memberInfo = person.UnwrapIfWrapped().GetType().Member("Name"); 48 | var name = (string)memberInfo.Get(person) + " updated"; 49 | memberInfo.Set(person, name); 50 | VerifyProperties(person, new { name }); 51 | }); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/ConstructorInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | using Fasterflect.Emitter; 22 | 23 | namespace Fasterflect 24 | { 25 | /// 26 | /// Extension methods for inspecting, invoking and working with constructors. 27 | /// 28 | public static class ConstructorInfoExtensions 29 | { 30 | /// 31 | /// Invokes the constructor with as arguments. 32 | /// Leave empty if the constructor has no argument. 33 | /// 34 | public static object CreateInstance( this ConstructorInfo ctorInfo, params object[] parameters ) 35 | { 36 | return ctorInfo.DelegateForCreateInstance()( parameters ); 37 | } 38 | 39 | /// 40 | /// Creates a delegate which can create instance based on the constructor . 41 | /// 42 | public static ConstructorInvoker DelegateForCreateInstance( this ConstructorInfo ctorInfo ) 43 | { 44 | return (ConstructorInvoker) new CtorInvocationEmitter( ctorInfo, Flags.InstanceAnyVisibility ).GetDelegate(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Services/DynamicTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using Fasterflect; 23 | using NUnit.Framework; 24 | using FasterflectTest.SampleModel.People; 25 | 26 | namespace FasterflectTest.Services 27 | { 28 | #if DOT_NET_4 29 | [TestFixture] 30 | public class DynamicTest 31 | { 32 | [Test] 33 | public void TestDynamicWrapper() 34 | { 35 | Person original = new Person( "Bruce Lee", 25 ); 36 | dynamic wrapper = new DynamicWrapper( original ); 37 | Assert.AreEqual( original.Name, wrapper.Name ); 38 | Assert.AreEqual( original.Age, wrapper.Age ); 39 | double distance; 40 | original.Walk( 10d, out distance ); 41 | Assert.AreEqual( 10d, distance ); 42 | wrapper.Walk( 10d, out distance ); 43 | //Assert.AreEqual( 20d, distance ); 44 | Assert.AreEqual( 20d, original.TryGetFieldValue( "metersTravelled" ) ); 45 | } 46 | 47 | [Test] 48 | public void TestDynamicBuilder() 49 | { 50 | dynamic obj = new DynamicBuilder(); 51 | obj.Value = 1; 52 | obj.GetMessage = new Func( () => "Value = " + obj.Value ); 53 | // verify 54 | Assert.AreEqual( "Value = 1", obj.GetMessage() ); 55 | // verify that we still work after updating member 56 | obj.Value = 5; 57 | Assert.AreEqual( "Value = 5", obj.GetMessage() ); 58 | } 59 | } 60 | #endif 61 | } 62 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Common/FormatOptions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | 21 | namespace Fasterflect 22 | { 23 | /// 24 | /// This enumeration allows you to customize the XML output of the ToXml extensions. 25 | /// 26 | [Flags] 27 | public enum FormatOptions 28 | { 29 | /// 30 | /// This option specifies the empty set of options and does not affect the output. 31 | /// 32 | None = 0, 33 | /// 34 | /// If this option is specified the generated XML will include an XML document header. 35 | /// 36 | AddHeader = 1, 37 | /// 38 | /// If this option is specified a line feed will be emitted after every XML element. 39 | /// 40 | NewLineAfterElement = 2, 41 | /// 42 | /// If this option is specified nested tags will be indented either 1 tab character 43 | /// (the default) or 4 space characters. 44 | /// 45 | Indent = 4, 46 | /// 47 | /// If this option is specified indentation will use spaces instead of tabs. 48 | /// 49 | UseSpaces = 8, 50 | /// 51 | /// This option, which combines AddHeader, NewLineAfterElement and Indent, provides the 52 | /// default set of options used. 53 | /// 54 | Default = AddHeader | NewLineAfterElement | Indent 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Elephant.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using FasterflectTest.SampleModel.Animals.Enumerations; 23 | 24 | namespace FasterflectTest.SampleModel.Animals 25 | { 26 | internal class Elephant : Mammal 27 | { 28 | #pragma warning disable 0169, 0649 29 | public int MethodInvoked { get; private set; } 30 | #pragma warning restore 0169, 0649 31 | 32 | #region Constructors 33 | public Elephant() : base( Climate.Hot, MovementCapabilities.Land ) 34 | { 35 | } 36 | #endregion 37 | 38 | #region Methods 39 | public void Eat() 40 | { 41 | MethodInvoked = 1; 42 | } 43 | public void Eat( string food ) 44 | { 45 | MethodInvoked = 2; 46 | } 47 | public void Eat( int count ) 48 | { 49 | MethodInvoked = 3; 50 | } 51 | public void Eat( int count, string food ) 52 | { 53 | MethodInvoked = 4; 54 | } 55 | public void Eat( double count, string food, bool isHay ) 56 | { 57 | MethodInvoked = 5; 58 | } 59 | 60 | public void Roar( int count ) 61 | { 62 | MethodInvoked = 10; 63 | } 64 | public void Roar( int count, int volume ) 65 | { 66 | MethodInvoked = 11; 67 | } 68 | public void Accept( char c ) 69 | { 70 | MethodInvoked = 12; 71 | } 72 | public void AcceptParams( params string[] args ) 73 | { 74 | MethodInvoked = 13; 75 | } 76 | #endregion 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Issues/IssueList2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using Fasterflect; 4 | using NUnit.Framework; 5 | 6 | namespace FasterflectTest.Issues 7 | { 8 | [TestFixture] 9 | public class IssueList2 10 | { 11 | [Test] 12 | public void ArrayListFailureDemo_Works() 13 | { 14 | var list = typeof(ArrayList).CreateInstance(); 15 | var add_with_object = list.GetType().DelegateForCallMethod( "Add", typeof(object) ); 16 | for( int i = 0; i < 10; i++ ) 17 | { 18 | add_with_object( list, i ); 19 | } 20 | var size = (int) list.GetPropertyValue( "Count" ); 21 | Assert.AreEqual( 10, size ); 22 | } 23 | 24 | // uncomment line 54 in LookupUtils to enable older code base behavior 25 | [Test] 26 | public void ArrayListFailureDemo_WorksButFailsWithOlderCodeBase() 27 | { 28 | var list = typeof(ArrayList).CreateInstance(); 29 | var add_with_int = list.GetType().DelegateForCallMethod( "Add", typeof(int) ); 30 | for (int i = 0; i < 10; i++) 31 | { 32 | add_with_int( list, i ); 33 | } 34 | var size = (int)list.GetPropertyValue("Count"); 35 | Assert.AreEqual( 10, size ); 36 | } 37 | 38 | [Test] 39 | public void Issue1() 40 | { 41 | var list = typeof(ArrayList).CreateInstance(); 42 | for (int i = 0; i < 10; i++) 43 | { 44 | list.CallMethod("Add", i); 45 | } 46 | var size = (int)list.GetPropertyValue("Count"); 47 | Assert.AreEqual( 10, size ); 48 | } 49 | 50 | class AClass 51 | { 52 | public AClass(object o) 53 | { 54 | } 55 | public int Add(object i) 56 | { 57 | Console.WriteLine( "object" ); 58 | return 1; 59 | } 60 | public int Add(int i) 61 | { 62 | Console.WriteLine( "int" ); 63 | return 1; 64 | } 65 | } 66 | 67 | [Test] 68 | public void Issue1a() 69 | { 70 | var list = typeof(AClass).CreateInstance(0); 71 | for (int i = 0; i < 10; i++) 72 | { 73 | list.CallMethod("Add", i); 74 | } 75 | } 76 | 77 | [Test] 78 | public void Issue2() 79 | { 80 | for( int i = 0; i < 10; i++ ) 81 | { 82 | var obj = typeof(AClass).CreateInstance(i); 83 | Assert.IsNotNull(obj); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/ArrayGetEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | using System.Reflection.Emit; 22 | 23 | namespace Fasterflect.Emitter 24 | { 25 | internal class ArrayGetEmitter : BaseEmitter 26 | { 27 | public ArrayGetEmitter( Type targetType ) 28 | : base(new CallInfo( targetType, null, Flags.InstanceAnyVisibility, MemberTypes.Method, 29 | Constants.ArrayGetterName, new[] { typeof(int) }, null, true )) 30 | { 31 | } 32 | 33 | protected internal override DynamicMethod CreateDynamicMethod() 34 | { 35 | return CreateDynamicMethod( Constants.ArrayGetterName, CallInfo.TargetType, 36 | Constants.ObjectType, new[] { Constants.ObjectType, Constants.IntType } ); 37 | } 38 | 39 | protected internal override Delegate CreateDelegate() 40 | { 41 | Type elementType = CallInfo.TargetType.GetElementType(); 42 | Generator.ldarg_0 // load array 43 | .castclass( CallInfo.TargetType ) // (T[])array 44 | .ldarg_1 // load index 45 | .ldelem( elementType ) // load array[index] 46 | .boxIfValueType( elementType ) // [box] return 47 | .ret(); 48 | return Method.CreateDelegate( typeof(ArrayElementGetter) ); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Animal.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.ComponentModel; 23 | using System.Diagnostics; 24 | using FasterflectTest.SampleModel.Animals.Attributes; 25 | using FasterflectTest.SampleModel.Animals.Enumerations; 26 | 27 | namespace FasterflectTest.SampleModel.Animals 28 | { 29 | [DebuggerDisplay("ID={id}, Type={GetType()}")] 30 | internal abstract class Animal 31 | { 32 | private static int nextId = 1; 33 | [Code("ID")] 34 | private readonly int id; 35 | [DefaultValue(null)] 36 | private DateTime? birthDay; 37 | 38 | public int ID { get { return id; } } 39 | public DateTime? BirthDay { get { return birthDay; } set { birthDay = value; } } 40 | public Climate ClimateRequirements { get; private set; } 41 | [Code("Movement")] 42 | public MovementCapabilities MovementCapabilities { get; private set; } 43 | 44 | public static int LastID { get { return nextId-1; } } 45 | 46 | protected Animal( Climate climateRequirements, MovementCapabilities movementCapabilities ) 47 | { 48 | id = nextId++; 49 | ClimateRequirements = climateRequirements; 50 | MovementCapabilities = movementCapabilities; 51 | } 52 | 53 | protected Animal( int id, Climate climateRequirements, MovementCapabilities movementCapabilities ) 54 | { 55 | this.id = id; 56 | ClimateRequirements = climateRequirements; 57 | MovementCapabilities = movementCapabilities; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Common/Utils.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2009 Buu Nguyen (http://www.buunguyen.net/blog) 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using System.Diagnostics; 24 | using System.Reflection; 25 | using Fasterflect.Emitter; 26 | 27 | namespace Fasterflect 28 | { 29 | [DebuggerStepThrough] 30 | internal static class Utils 31 | { 32 | public static Type GetTypeAdjusted( this object obj ) 33 | { 34 | var wrapper = obj as ValueTypeHolder; 35 | return wrapper == null 36 | ? obj is Type ? obj as Type : obj.GetType() 37 | : wrapper.Value.GetType(); 38 | } 39 | 40 | public static Type[] ToTypeArray(this ParameterInfo[] parameters) 41 | { 42 | if (parameters.Length == 0) 43 | return Type.EmptyTypes; 44 | var types = new Type[parameters.Length]; 45 | for (int i = 0; i < types.Length; i++) 46 | { 47 | types[i] = parameters[i].ParameterType; 48 | } 49 | return types; 50 | } 51 | 52 | public static Type[] ToTypeArray(this object[] objects) 53 | { 54 | if (objects.Length == 0) 55 | return Type.EmptyTypes; 56 | var types = new Type[objects.Length]; 57 | for (int i = 0; i < types.Length; i++) 58 | { 59 | var obj = objects[ i ]; 60 | types[i] = obj != null ? obj.GetType() : null; 61 | } 62 | return types; 63 | } 64 | 65 | public static void ForEach( this IEnumerable source, Action action ) 66 | { 67 | foreach( T element in source ) 68 | { 69 | action( element ); 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/ArraySetEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | using System.Reflection.Emit; 22 | 23 | namespace Fasterflect.Emitter 24 | { 25 | internal class ArraySetEmitter : BaseEmitter 26 | { 27 | public ArraySetEmitter( Type targetType ) 28 | : base(new CallInfo(targetType, null, Flags.InstanceAnyVisibility, MemberTypes.Method, Constants.ArraySetterName, 29 | new[] { typeof(int), targetType.GetElementType() }, null, false)) 30 | { 31 | } 32 | 33 | protected internal override DynamicMethod CreateDynamicMethod() 34 | { 35 | return CreateDynamicMethod( Constants.ArraySetterName, CallInfo.TargetType, null, 36 | new[] { Constants.ObjectType, Constants.IntType, Constants.ObjectType } ); 37 | } 38 | 39 | protected internal override Delegate CreateDelegate() 40 | { 41 | Type elementType = CallInfo.TargetType.GetElementType(); 42 | Generator.ldarg_0 // load array 43 | .castclass( CallInfo.TargetType ) // (T[])array 44 | .ldarg_1 // load index 45 | .ldarg_2 // load value 46 | .CastFromObject( elementType ) // (unbox | cast) value 47 | .stelem( elementType ) // array[index] = value 48 | .ret(); 49 | return Method.CreateDelegate( typeof(ArrayElementSetter) ); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Fasterflect.Netstandard.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.5;net45;net35;net46;netstandard2.0 5 | Fasterflect.Netstandard 6 | Fasterflect.Netstandard 7 | false 8 | false 9 | false 10 | A port of Fasterflect to Netstandard. 11 | https://github.com/HelloKitty/fasterflect 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Buu Nguyen, Morten Mertner, Andrew Blakely 14 | Buu Nguyen, Morten Mertner, Andrew Blakely 15 | https://github.com/HelloKitty/fasterflect 16 | git 17 | fasterflect netstandard faster flect net standard netcore core port 18 | 19 | 20 | 21 | bin\Release\netstandard1.5\Fasterflect.Netstandard.xml 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Services/Probing/ConstructorMap.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Reflection; 23 | 24 | namespace Fasterflect.Probing 25 | { 26 | internal class ConstructorMap : MethodMap 27 | { 28 | private ConstructorInvoker invoker; 29 | 30 | public ConstructorMap( ConstructorInfo constructor, string[] paramNames, Type[] parameterTypes, 31 | object[] sampleParamValues, bool mustUseAllParameters ) 32 | : base(constructor, paramNames, parameterTypes, sampleParamValues, mustUseAllParameters) 33 | { 34 | } 35 | 36 | #region UpdateMembers Private Helper Method 37 | private void UpdateMembers(object target, object[] row) 38 | { 39 | for( int i = 0; i < row.Length; i++ ) 40 | { 41 | if( parameterReflectionMask[ i ] ) 42 | { 43 | MemberInfo member = members[ i ]; 44 | if( member != null ) 45 | { 46 | object value = parameterTypeConvertMask[ i ] ? TypeConverter.Get( member.Type(), row[ i ] ) : row[ i ]; 47 | member.Set( target, value ); 48 | } 49 | } 50 | } 51 | } 52 | #endregion 53 | 54 | public override object Invoke( object[] row ) 55 | { 56 | object[] methodParameters = isPerfectMatch ? row : PrepareParameters(row); 57 | object result = invoker.Invoke(methodParameters); 58 | if (!isPerfectMatch && AnySet(parameterReflectionMask)) 59 | UpdateMembers(result, row); 60 | return result; 61 | } 62 | 63 | internal override void InitializeInvoker() 64 | { 65 | invoker = type.DelegateForCreateInstance( GetParamTypes() ); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Fasterflect.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.8 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D839B827-0ECA-4151-9A07-9161E209E23F}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{16D1FC09-2631-40EE-89CA-893073BCDA68}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fasterflect.Netstandard", "src\Fasterflect.Netstandard\Fasterflect.Netstandard.csproj", "{5C6966B7-610E-42D2-9661-C80C46392124}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fasterflect.Netframework.Tests", "tests\Fasterflect.Netframework.Tests\Fasterflect.Netframework.Tests.csproj", "{4EF5F3A5-53AF-4291-ABA0-0DD6DCB2E89B}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {5C6966B7-610E-42D2-9661-C80C46392124}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {5C6966B7-610E-42D2-9661-C80C46392124}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {5C6966B7-610E-42D2-9661-C80C46392124}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {5C6966B7-610E-42D2-9661-C80C46392124}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {4EF5F3A5-53AF-4291-ABA0-0DD6DCB2E89B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {4EF5F3A5-53AF-4291-ABA0-0DD6DCB2E89B}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {4EF5F3A5-53AF-4291-ABA0-0DD6DCB2E89B}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {4EF5F3A5-53AF-4291-ABA0-0DD6DCB2E89B}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | GlobalSection(NestedProjects) = preSolution 33 | {5C6966B7-610E-42D2-9661-C80C46392124} = {D839B827-0ECA-4151-9A07-9161E209E23F} 34 | {4EF5F3A5-53AF-4291-ABA0-0DD6DCB2E89B} = {16D1FC09-2631-40EE-89CA-893073BCDA68} 35 | EndGlobalSection 36 | GlobalSection(ExtensibilityGlobals) = postSolution 37 | SolutionGuid = {A380C532-85D3-4F51-BB98-D8947FDF69D0} 38 | EndGlobalSection 39 | GlobalSection(TestCaseManagementSettings) = postSolution 40 | CategoryFile = Fasterflect.vsmdi 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/Animals/Lion.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.ComponentModel; 23 | using System.Reflection; 24 | using Fasterflect; 25 | using FasterflectTest.SampleModel.Animals.Attributes; 26 | using FasterflectTest.SampleModel.Animals.Enumerations; 27 | 28 | namespace FasterflectTest.SampleModel.Animals 29 | { 30 | [Zone(Zone.Savannah)] 31 | [Serializable] 32 | internal class Lion : Mammal 33 | { 34 | #pragma warning disable 0169, 0649 35 | [Code("Field")] 36 | private DateTime lastMealTime = DateTime.MinValue; 37 | 38 | [Code("ReadWrite Property")] 39 | [DefaultValue("Simba")] 40 | public string Name { get; private set; } 41 | 42 | [Code("ReadOnly Property")] 43 | public bool IsHungry { get { return DateTime.Now.AddHours( -12 ) > lastMealTime; } } 44 | 45 | public int ConstructorInstanceUsed { get; private set; } 46 | #pragma warning restore 0169, 0649 47 | 48 | #region Constructors 49 | public Lion() : this( typeof(Lion).Property( "Name" ).Attribute().Value.ToString() ) 50 | { 51 | ConstructorInstanceUsed = 1; 52 | } 53 | 54 | public Lion( string name ) : base( Climate.Hot, MovementCapabilities.Land ) 55 | { 56 | Name = name; 57 | ConstructorInstanceUsed = 2; 58 | } 59 | 60 | public Lion( int id ) : this( id, typeof(Lion).Property( "Name" ).Attribute().Value.ToString() ) 61 | { 62 | ConstructorInstanceUsed = 3; 63 | } 64 | 65 | public Lion( int id, string name ) : base( id, Climate.Hot, MovementCapabilities.Land ) 66 | { 67 | Name = name; 68 | ConstructorInstanceUsed = 4; 69 | } 70 | #endregion 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/ArrayTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using Fasterflect; 23 | using FasterflectTest.Common; 24 | using FasterflectTest.SampleModel.People; 25 | using NUnit.Framework; 26 | 27 | namespace FasterflectTest.Invocation 28 | { 29 | [TestFixture] 30 | public class ArrayTest : BaseInvocationTest 31 | { 32 | public ArrayTest() : base(typeof(Person[]), typeof(PersonStruct[])) {} 33 | 34 | [Test] 35 | public void TestConstructArrays() 36 | { 37 | RunWith((Type type) => 38 | { 39 | var obj = type.CreateInstance(10); 40 | Assert.IsNotNull(obj); 41 | Assert.AreEqual(10, obj.GetPropertyValue("Length")); 42 | }); 43 | } 44 | 45 | [Test] 46 | public void TestGetSetElements() 47 | { 48 | RunWith((Type type) => 49 | { 50 | var array = type.CreateInstance(10); 51 | var instance = type.GetElementType().CreateInstance().WrapIfValueType(); 52 | instance.SetFieldValue( "name", "John" ); 53 | array.SetElement(1, instance.UnwrapIfWrapped()); 54 | VerifyFields( array.GetElement( 1 ).WrapIfValueType(), new { name = "John" } ); 55 | }); 56 | } 57 | 58 | [Test] 59 | public void TestGetSetElementsOnIntArray() 60 | { 61 | var array = typeof(int[]).CreateInstance( 20 ); 62 | array.SetElement( 5, 10 ); 63 | Assert.AreEqual( 10, array.GetElement( 5 ) ); 64 | } 65 | 66 | [Test] 67 | public void TestGetSetElementsOnArrayProperty() 68 | { 69 | var employee = EmployeeType.CreateInstance(); 70 | employee.SetPropertyValue("Subordinates", new Employee[10]); 71 | var subordinates = employee.GetPropertyValue( "Subordinates" ); 72 | subordinates.SetElement(5, employee); 73 | Assert.AreEqual(employee, subordinates.GetElement(5)); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/ArrayExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using Fasterflect.Emitter; 21 | 22 | namespace Fasterflect 23 | { 24 | /// 25 | /// Extension methods for working with arrays. 26 | /// 27 | public static class ArrayExtensions 28 | { 29 | #region Array Access 30 | /// 31 | /// Sets to the element at position of . 32 | /// 33 | /// . 34 | public static object SetElement( this object array, int index, object value ) 35 | { 36 | ((Array) array).SetValue( value, index ); 37 | return array; 38 | } 39 | 40 | /// 41 | /// Gets the element at position of . 42 | /// 43 | public static object GetElement( this object array, int index ) 44 | { 45 | return ((Array) array).GetValue( index ); 46 | } 47 | 48 | /// 49 | /// Creates a delegate which can set element of . 50 | /// 51 | public static ArrayElementSetter DelegateForSetElement( this Type arrayType ) 52 | { 53 | return (ArrayElementSetter) new ArraySetEmitter( arrayType ).GetDelegate(); 54 | } 55 | 56 | /// 57 | /// Creates a delegate which can retrieve element of . 58 | /// 59 | public static ArrayElementGetter DelegateForGetElement( this Type arrayType ) 60 | { 61 | return (ArrayElementGetter) new ArrayGetEmitter( arrayType ).GetDelegate(); 62 | } 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Lookup/AssemblyTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using System.Reflection; 24 | using Fasterflect; 25 | using NUnit.Framework; 26 | 27 | namespace FasterflectTest.Lookup 28 | { 29 | [TestFixture] 30 | public class AssemblyTest 31 | { 32 | #region Types() 33 | [Test] 34 | public void TestFindTypes() 35 | { 36 | Assembly assembly = Assembly.GetAssembly( typeof(int) ); 37 | IList types = assembly.Types(); 38 | Assert.IsNotNull( types ); 39 | Assert.IsTrue( types.Count > 1000 ); 40 | } 41 | 42 | [Test] 43 | public void TestFindTypesByEmptyNameListShouldReturnAllTypes() 44 | { 45 | Assembly assembly = Assembly.GetAssembly( typeof(int) ); 46 | IList types = assembly.Types( new string[ 0 ] ); 47 | Assert.IsNotNull( types ); 48 | Assert.IsTrue( types.Count > 1000 ); 49 | 50 | types = assembly.Types( null ); 51 | Assert.IsNotNull( types ); 52 | Assert.IsTrue( types.Count > 1000 ); 53 | } 54 | 55 | [Test] 56 | public void TestFindTypesShouldReturnEmptyListIfNotFound() 57 | { 58 | Assembly assembly = Assembly.GetAssembly( typeof(int) ); 59 | IList types = assembly.Types( "UrzgHafn" ); 60 | Assert.IsNotNull( types ); 61 | Assert.AreEqual( 0, types.Count ); 62 | } 63 | 64 | [Test] 65 | public void TestFindTypesByName() 66 | { 67 | Assembly assembly = Assembly.GetAssembly( typeof(int) ); 68 | IList types = assembly.Types( "Int32" ); 69 | Assert.IsNotNull( types ); 70 | Assert.AreEqual( 1, types.Count ); 71 | } 72 | 73 | [Test] 74 | public void TestFindTypesByPartialName() 75 | { 76 | Assembly assembly = Assembly.GetAssembly( typeof(int) ); 77 | IList types = assembly.Types( Flags.PartialNameMatch, "Engine" ); 78 | Assert.IsNotNull( types ); 79 | Assert.AreEqual( 2, types.Count ); 80 | } 81 | #endregion 82 | } 83 | } 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/DynamicReflection/DynamicBuilder.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | #if DOT_NET_4 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Dynamic; 23 | 24 | namespace Fasterflect 25 | { 26 | internal sealed class DynamicBuilder : DynamicObject 27 | { 28 | private readonly Dictionary members = new Dictionary (); 29 | 30 | #region DynamicObject Overrides 31 | /// 32 | /// Assigns the given value to the specified member, overwriting any previous definition if one existed. 33 | /// 34 | public override bool TrySetMember( SetMemberBinder binder, object value ) 35 | { 36 | members[ binder.Name ] = value; 37 | return true; 38 | } 39 | 40 | /// 41 | /// Gets the value of the specified member. 42 | /// 43 | public override bool TryGetMember( GetMemberBinder binder, out object result ) 44 | { 45 | if( members.ContainsKey( binder.Name ) ) 46 | { 47 | result = members[ binder.Name ]; 48 | return true; 49 | } 50 | return base.TryGetMember( binder, out result ); 51 | } 52 | 53 | /// 54 | /// Invokes the specified member (if it is a delegate). 55 | /// 56 | public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, out object result ) 57 | { 58 | object member; 59 | if( members.TryGetValue( binder.Name, out member ) ) 60 | { 61 | var method = member as Delegate; 62 | if( method != null ) 63 | { 64 | result = method.DynamicInvoke( args ); 65 | return true; 66 | } 67 | } 68 | return base.TryInvokeMember( binder, args, out result ); 69 | } 70 | 71 | /// 72 | /// Gets a list of all dynamically defined members. 73 | /// 74 | public override IEnumerable GetDynamicMemberNames() 75 | { 76 | return members.Keys; 77 | } 78 | #endregion 79 | } 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Services/XmlTransformerTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using Fasterflect; 24 | using NUnit.Framework; 25 | using FasterflectTest.SampleModel.People; 26 | 27 | namespace FasterflectTest.Services 28 | { 29 | [TestFixture] 30 | public class XmlTransformerTest 31 | { 32 | #region ToXml 33 | //[Test] 34 | //public void TestToXml() 35 | //{ 36 | // string xml = "{0}" + 37 | // "{0}{1}Bruce Lee{0}{1}25{0}{1}" + 38 | // "0{0}{0}"; 39 | // string expected = string.Format( xml, Environment.NewLine, "\t" ); 40 | // Person person = new Person( "Bruce Lee", 25 ); 41 | // Assert.AreEqual( expected, person.ToXml() ); 42 | //} 43 | 44 | [Test] 45 | public void TestToXml() 46 | { 47 | string xml = "{0}" + 48 | "{0}{1}{0}"; 49 | string name = string.Format( "{1}Bruce Lee{0}", Environment.NewLine, "\t" ); 50 | string age = string.Format( "{1}25{0}", Environment.NewLine, "\t" ); 51 | string mt = string.Format( "{1}0{0}", Environment.NewLine, "\t" ); 52 | var expected = new List(); 53 | expected.Add( string.Format( xml, Environment.NewLine, name + age + mt ) ); 54 | expected.Add( string.Format( xml, Environment.NewLine, name + mt + age ) ); 55 | expected.Add( string.Format( xml, Environment.NewLine, age + name + mt ) ); 56 | expected.Add( string.Format( xml, Environment.NewLine, age + mt + name ) ); 57 | expected.Add( string.Format( xml, Environment.NewLine, mt + age + name ) ); 58 | expected.Add( string.Format( xml, Environment.NewLine, mt + name + age ) ); 59 | Person person = new Person( "Bruce Lee", 25 ); 60 | Assert.IsTrue( expected.Contains( person.ToXml() ) ); 61 | } 62 | #endregion 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Lookup/TryGetSetTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using Fasterflect; 22 | using FasterflectTest.SampleModel.Animals; 23 | using NUnit.Framework; 24 | 25 | namespace FasterflectTest.Lookup 26 | { 27 | [TestFixture] 28 | public class TryGetSetTest 29 | { 30 | [Test] 31 | public void TestTryGetSetField() 32 | { 33 | Lion lion = new Lion( 42, "Scar" ); 34 | // tryget 35 | Assert.IsNull( lion.TryGetFieldValue( "name" ) ); 36 | Assert.IsNull( lion.TryGetFieldValue( "ID" ) ); 37 | Assert.AreEqual( 42, lion.TryGetFieldValue( "id" ) ); 38 | Assert.AreEqual( 42, lion.TryGetFieldValue( "ID", Flags.InstanceAnyVisibility | Flags.IgnoreCase ) ); 39 | // tryset 40 | Assert.IsFalse( lion.TrySetFieldValue( "missing", false ) ); 41 | Assert.IsTrue( lion.TrySetFieldValue( "id", 43 ) ); 42 | Assert.AreEqual( 43, lion.ID ); 43 | } 44 | 45 | [Test] 46 | public void TestTryGetSetProperty() 47 | { 48 | Lion lion = new Lion( 42, "Scar" ); 49 | // tryget 50 | Assert.IsNull( lion.TryGetPropertyValue( "missing" ) ); 51 | Assert.AreEqual( 42, lion.TryGetPropertyValue( "ID" ) ); 52 | Assert.AreEqual( "Scar", lion.TryGetPropertyValue( "Name" ) ); 53 | // tryset 54 | Assert.IsFalse( lion.TrySetPropertyValue( "missing", false ) ); 55 | Assert.IsTrue( lion.TrySetPropertyValue( "Name", "Simba" ) ); 56 | Assert.AreEqual( "Simba", lion.Name ); 57 | } 58 | 59 | [Test] 60 | public void TestTryGetSetMember() 61 | { 62 | Lion lion = new Lion( 42, "Scar" ); 63 | // tryget 64 | Assert.IsNull( lion.TryGetValue( "missing" ) ); 65 | Assert.AreEqual( 42, lion.TryGetValue( "id" ) ); 66 | Assert.AreEqual( "Scar", lion.TryGetValue( "Name" ) ); 67 | // tryset 68 | Assert.IsFalse( lion.TrySetValue( "missing", false ) ); 69 | Assert.IsTrue( lion.TrySetValue( "id", 43 ) ); 70 | Assert.AreEqual( 43, lion.ID ); 71 | Assert.IsTrue( lion.TrySetValue( "ID", 44, Flags.InstanceAnyVisibility | Flags.IgnoreCase ) ); 72 | Assert.IsTrue( lion.TrySetValue( "Name", "Simba" ) ); 73 | Assert.AreEqual( 44, lion.ID ); 74 | Assert.AreEqual( "Simba", lion.Name ); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Common/BaseTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Linq; 23 | using Fasterflect; 24 | using NUnit.Framework; 25 | 26 | namespace FasterflectTest.Common 27 | { 28 | public abstract class BaseTest 29 | { 30 | protected readonly Type[] Types; 31 | 32 | protected BaseTest( Type[] types ) 33 | { 34 | Types = types; 35 | } 36 | 37 | protected static void VerifyProperties( Type type, object sample ) 38 | { 39 | var properties = sample.GetType().Properties(); 40 | properties.ForEach( propInfo => Assert.AreEqual( propInfo.Get( sample ), 41 | type.GetPropertyValue( propInfo.Name.FirstCharUpper() ) ) ); 42 | } 43 | 44 | protected static void VerifyProperties( object obj, object sample ) 45 | { 46 | var properties = sample.GetType().Properties(); 47 | properties.ForEach( propInfo => Assert.AreEqual( propInfo.Get( sample ), 48 | obj.GetPropertyValue( propInfo.Name.FirstCharUpper() ) ) ); 49 | } 50 | 51 | protected static void VerifyFields( Type type, object sample ) 52 | { 53 | var properties = sample.GetType().Properties(); 54 | properties.ForEach( propInfo => Assert.AreEqual( propInfo.Get( sample ), type.GetFieldValue( propInfo.Name.FirstCharLower() ) ) ); 55 | } 56 | 57 | protected static void VerifyFields( object obj, object sample ) 58 | { 59 | var properties = sample.GetType().Properties(); 60 | properties.ForEach( propInfo => Assert.AreEqual( propInfo.Get( sample ), obj.GetFieldValue( propInfo.Name.FirstCharLower() ) ) ); 61 | } 62 | 63 | protected void RunWith( Action assertionAction ) 64 | { 65 | Types.ForEach( assertionAction ); 66 | } 67 | 68 | protected void RunWith( Action assertionAction ) 69 | { 70 | Types.Select( t => t.CreateInstance().WrapIfValueType() ).ForEach( assertionAction ); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Probing/TryCallMethodTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using Fasterflect; 23 | using FasterflectTest.SampleModel.Animals; 24 | using NUnit.Framework; 25 | 26 | namespace FasterflectTest.Probing 27 | { 28 | [TestFixture] 29 | public class TryCallMethodTest 30 | { 31 | [Test] 32 | public void TestTryCallWithEmptyArgumentShouldInvokeMethod1() 33 | { 34 | var obj = new Elephant(); 35 | obj.TryCallMethod( "Eat", true, new { } ); 36 | Assert.AreEqual( 1, obj.MethodInvoked ); 37 | // check that we also work when passing in unused parameters 38 | obj.TryCallMethod( "Eat", false, new { size=1 } ); 39 | Assert.AreEqual( 1, obj.MethodInvoked ); 40 | } 41 | 42 | [Test] 43 | public void TestTryCallWithFoodArgumentShouldInvokeMethod2() 44 | { 45 | var obj = new Elephant(); 46 | obj.TryCallMethod( "Eat", true, new { food="hay" } ); 47 | Assert.AreEqual( 2, obj.MethodInvoked ); 48 | } 49 | 50 | [Test] 51 | public void TestTryCallWithCountArgumentsShouldInvokeMethod3() 52 | { 53 | var obj = new Elephant(); 54 | obj.TryCallMethod( "Eat", true, new { count=2 } ); 55 | Assert.AreEqual( 3, obj.MethodInvoked ); 56 | } 57 | 58 | [Test] 59 | public void TestTryCallWithCountAndFoodArgumentsShouldInvokeMethod4() 60 | { 61 | var obj = new Elephant(); 62 | obj.TryCallMethod( "Eat", true, new { count=2, food="hay" } ); 63 | Assert.AreEqual( 4, obj.MethodInvoked ); 64 | } 65 | 66 | [Test] 67 | public void TestTryCallWithCountAndFoodAndIsHayArgumentsShouldInvokeMethod5() 68 | { 69 | var obj = new Elephant(); 70 | obj.TryCallMethod( "Eat", true, new { count=2.0, food="hay", isHay=true } ); 71 | Assert.AreEqual( 5, obj.MethodInvoked ); 72 | // try with argument that must be type converted 73 | obj.TryCallMethod( "Eat", true, new { count=2, food="hay", isHay=true } ); 74 | Assert.AreEqual( 5, obj.MethodInvoked ); 75 | } 76 | 77 | [Test] 78 | [ExpectedException(typeof(MissingMethodException))] 79 | public void TestTryCallWithNonMatchShouldThrow() 80 | { 81 | var obj = new Elephant(); 82 | obj.TryCallMethod( "Eat", true, new { size=1 } ); 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/ValueTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System.Reflection; 20 | using Fasterflect.Emitter; 21 | 22 | namespace Fasterflect 23 | { 24 | /// 25 | /// Extension methods for working with types. 26 | /// 27 | public static class ValueTypeExtensions 28 | { 29 | /// 30 | /// Returns a wrapper instance if 31 | /// is a value type. Otherwise, returns . 32 | /// 33 | ///An object to be examined. 34 | ///A wrapper instance if 35 | /// is a value type, or itself if it's a reference type. 36 | public static object WrapIfValueType( this object obj ) 37 | { 38 | return obj.GetType().GetTypeInfo().IsValueType ? new ValueTypeHolder( obj ) : obj; 39 | } 40 | 41 | /// 42 | /// Returns a wrapped object if is an instance of . 43 | /// 44 | ///An object to be "erased". 45 | ///The object wrapped by if the latter is of type . Otherwise, 46 | /// return . 47 | public static object UnwrapIfWrapped( this object obj ) 48 | { 49 | var holder = obj as ValueTypeHolder; 50 | return holder == null ? obj : holder.Value; 51 | } 52 | 53 | /// 54 | /// Determines whether is a wrapped object (instance of ). 55 | /// 56 | /// The object to check. 57 | /// Returns true if is a wrapped object (instance of ). 58 | public static bool IsWrapped( this object obj ) 59 | { 60 | return obj as ValueTypeHolder != null; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Lookup/ParameterTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using Fasterflect; 22 | using NUnit.Framework; 23 | using FasterflectTest.SampleModel.Animals; 24 | 25 | namespace FasterflectTest.Lookup 26 | { 27 | [TestFixture] 28 | public class ParameterTest 29 | { 30 | [Test] 31 | public void TestFindParameterDefaultValue() 32 | { 33 | var method = typeof(Snake).Method( "Move" ); 34 | Assert.IsNotNull( method ); 35 | var parameters = method.Parameters(); 36 | Assert.IsNotNull( parameters ); 37 | Assert.AreEqual( 1, parameters.Count ); 38 | var parameter = parameters[ 0 ]; 39 | Assert.IsTrue( parameter.HasDefaultValue() ); 40 | Assert.AreEqual( 100d, parameter.DefaultValue() ); 41 | } 42 | 43 | [Test] 44 | public void TestParameterHasName() 45 | { 46 | // Zoo.RegisterClass( string @class, string _section, string __name, int size ) 47 | var method = typeof(Zoo).Method( "RegisterClass" ); 48 | Assert.IsNotNull( method ); 49 | var parameters = method.Parameters(); 50 | Assert.IsNotNull( parameters ); 51 | Assert.AreEqual( 4, parameters.Count ); 52 | Assert.IsTrue( parameters[ 0 ].HasName( "class" ) ); 53 | Assert.IsTrue( parameters[ 0 ].HasName( "_class" ) ); 54 | Assert.IsTrue( parameters[ 1 ].HasName( "section" ) ); 55 | Assert.IsTrue( parameters[ 1 ].HasName( "_section" ) ); 56 | Assert.IsFalse( parameters[ 1 ].HasName( "__section" ) ); 57 | Assert.IsFalse( parameters[ 2 ].HasName( "name" ) ); 58 | Assert.IsFalse( parameters[ 2 ].HasName( "_name" ) ); 59 | Assert.IsTrue( parameters[ 2 ].HasName( "__name" ) ); 60 | } 61 | 62 | [Test] 63 | public void TestParameterIsNullable() 64 | { 65 | var method = typeof(Snake).Method( "Move" ); 66 | Assert.IsNotNull( method ); 67 | var parameters = method.Parameters(); 68 | Assert.IsNotNull( parameters ); 69 | Assert.AreEqual( 1, parameters.Count ); 70 | Assert.IsFalse( parameters[ 0 ].IsNullable() ); 71 | 72 | method = typeof(Snake).Method( "Bite" ); 73 | Assert.IsNotNull( method ); 74 | parameters = method.Parameters(); 75 | Assert.IsNotNull( parameters ); 76 | Assert.AreEqual( 1, parameters.Count ); 77 | Assert.IsTrue( parameters[ 0 ].IsNullable() ); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/DynamicReflection/DynamicWrapper.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | #if DOT_NET_4 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Dynamic; 23 | using System.Linq; 24 | 25 | namespace Fasterflect 26 | { 27 | internal sealed class DynamicWrapper : DynamicObject 28 | { 29 | private readonly object target; 30 | 31 | #region Constructors 32 | public DynamicWrapper( object target ) 33 | { 34 | this.target = target; 35 | } 36 | public DynamicWrapper( ref ValueType target ) 37 | { 38 | this.target = target.WrapIfValueType(); 39 | } 40 | #endregion 41 | 42 | #region DynamicObject Overrides 43 | /// 44 | /// Sets the member on the target to the given value. Returns true if the value was 45 | /// actually written to the underlying member. 46 | /// 47 | public override bool TrySetMember( SetMemberBinder binder, object value ) 48 | { 49 | return target.TrySetValue( binder.Name, value ); 50 | } 51 | 52 | /// 53 | /// Gets the member on the target and assigns it to the result parameter. Returns 54 | /// true if a value other than null was found and false otherwise. 55 | /// 56 | public override bool TryGetMember( GetMemberBinder binder, out object result ) 57 | { 58 | result = target.TryGetValue( binder.Name ); 59 | return result != null; 60 | } 61 | 62 | /// 63 | /// Invokes the method specified and assigns the result to the result parameter. Returns 64 | /// true if a method to invoke was found and false otherwise. 65 | /// 66 | public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, out object result ) 67 | { 68 | var bindingFlags = Flags.InstanceAnyVisibility | Flags.IgnoreParameterModifiers; 69 | var method = target.GetType().Method( binder.Name, args.ToTypeArray(), bindingFlags ); 70 | result = method == null ? null : method.Call( target, args ); 71 | return method != null; 72 | } 73 | 74 | /// 75 | /// Gets all member names from the underlying instance. 76 | /// 77 | public override IEnumerable GetDynamicMemberNames() 78 | { 79 | return target.GetType().Members().Select( m => m.Name ); 80 | } 81 | #endregion 82 | } 83 | } 84 | #endif 85 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/InvocationEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | 22 | namespace Fasterflect.Emitter 23 | { 24 | internal abstract class InvocationEmitter : BaseEmitter 25 | { 26 | protected InvocationEmitter(CallInfo callInfo) 27 | : base(callInfo) 28 | { 29 | } 30 | 31 | protected byte CreateLocalsForByRefParams( byte paramArrayIndex, MethodBase invocationInfo ) 32 | { 33 | var paramTypes = CallInfo.MethodParamTypes ?? CallInfo.ParamTypes; 34 | byte numberOfByRefParams = 0; 35 | var parameters = invocationInfo.GetParameters(); 36 | for( int i = 0; i < paramTypes.Length; i++ ) 37 | { 38 | Type paramType = paramTypes[ i ]; 39 | if( paramType.IsByRef ) 40 | { 41 | Type type = paramType.GetElementType(); 42 | Generator.DeclareLocal( type ); 43 | if( !parameters[ i ].IsOut ) // no initialization necessary is 'out' parameter 44 | { 45 | Generator.ldarg( paramArrayIndex ) 46 | .ldc_i4( i ) 47 | .ldelem_ref 48 | .CastFromObject( type ) 49 | .stloc( numberOfByRefParams ) 50 | .end(); 51 | } 52 | numberOfByRefParams++; 53 | } 54 | } 55 | return numberOfByRefParams; 56 | } 57 | 58 | protected void AssignByRefParamsToArray( int paramArrayIndex ) 59 | { 60 | var paramTypes = CallInfo.MethodParamTypes ?? CallInfo.ParamTypes; 61 | byte currentByRefParam = 0; 62 | for( int i = 0; i < paramTypes.Length; i++ ) 63 | { 64 | Type paramType = paramTypes[ i ]; 65 | if( paramType.IsByRef ) 66 | { 67 | Generator.ldarg( paramArrayIndex ) 68 | .ldc_i4( i ) 69 | .ldloc( currentByRefParam++ ) 70 | .boxIfValueType( paramType.GetElementType() ) 71 | .stelem_ref 72 | .end(); 73 | } 74 | } 75 | } 76 | 77 | protected void PushParamsOrLocalsToStack( int paramArrayIndex ) 78 | { 79 | var paramTypes = CallInfo.MethodParamTypes ?? CallInfo.ParamTypes; 80 | byte currentByRefParam = 0; 81 | for( int i = 0; i < paramTypes.Length; i++ ) 82 | { 83 | Type paramType = paramTypes[ i ]; 84 | if( paramType.IsByRef ) 85 | { 86 | Generator.ldloca_s( currentByRefParam++ ); 87 | } 88 | else 89 | { 90 | Generator.ldarg( paramArrayIndex ) 91 | .ldc_i4( i ) 92 | .ldelem_ref 93 | .CastFromObject( paramType ); 94 | } 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/MapCallInfo.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Diagnostics; 21 | using System.Linq; 22 | using System.Reflection; 23 | 24 | namespace Fasterflect.Emitter 25 | { 26 | /// 27 | /// Stores all necessary information to construct a dynamic method for member mapping. 28 | /// 29 | [DebuggerStepThrough] 30 | internal class MapCallInfo : CallInfo 31 | { 32 | public Type SourceType { get; private set; } 33 | public MemberTypes SourceMemberTypes { get; private set; } 34 | public MemberTypes TargetMemberTypes { get; private set; } 35 | public string[] Names { get; private set; } 36 | 37 | public MapCallInfo( Type targetType, Type[] genericTypes, Flags bindingFlags, MemberTypes memberTypes, string name, Type[] parameterTypes, MemberInfo memberInfo, bool isReadOperation, Type sourceType, MemberTypes sourceMemberTypes, MemberTypes targetMemberTypes, string[] names ) : base( targetType, genericTypes, bindingFlags, memberTypes, name, parameterTypes, memberInfo, isReadOperation ) 38 | { 39 | SourceType = sourceType; 40 | SourceMemberTypes = sourceMemberTypes; 41 | TargetMemberTypes = targetMemberTypes; 42 | Names = names; 43 | } 44 | 45 | public override bool Equals( object obj ) 46 | { 47 | var other = obj as MapCallInfo; 48 | if( other == null ) 49 | { 50 | return false; 51 | } 52 | if( ! base.Equals( obj ) ) 53 | { 54 | return false; 55 | } 56 | if( other.SourceType != SourceType || 57 | other.SourceMemberTypes != SourceMemberTypes || 58 | other.TargetMemberTypes != TargetMemberTypes || 59 | (other.Names == null && Names != null) || 60 | (other.Names != null && Names == null) || 61 | (other.Names != null && Names != null && other.Names.Length != Names.Length) ) 62 | { 63 | return false; 64 | } 65 | if( other.Names != null && Names != null ) 66 | { 67 | for( int i = 0; i < Names.Length; i++ ) 68 | { 69 | if( Names[ i ] != other.Names[ i ] ) 70 | { 71 | return false; 72 | } 73 | } 74 | } 75 | return true; 76 | } 77 | 78 | public override int GetHashCode() 79 | { 80 | int hash = base.GetHashCode() + SourceType.GetHashCode() * SourceMemberTypes.GetHashCode() * TargetMemberTypes.GetHashCode(); 81 | for( int i = 0; i < Names.Length; i++ ) 82 | { 83 | hash += Names[ i ].GetHashCode() * (i+1); 84 | } 85 | return hash; 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/FieldInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System.Reflection; 20 | using Fasterflect.Emitter; 21 | 22 | namespace Fasterflect 23 | { 24 | /// 25 | /// Extension methods for inspecting and working with fields. 26 | /// 27 | public static class FieldInfoExtensions 28 | { 29 | /// 30 | /// Sets the static field identified by to the specified . 31 | /// 32 | public static void Set( this FieldInfo fieldInfo, object value ) 33 | { 34 | fieldInfo.DelegateForSetFieldValue()( null, value ); 35 | } 36 | 37 | /// 38 | /// Sets the instance field identified by on the given 39 | /// to the specified . 40 | /// 41 | public static void Set( this FieldInfo fieldInfo, object obj, object value ) 42 | { 43 | fieldInfo.DelegateForSetFieldValue()( obj, value ); 44 | } 45 | 46 | /// 47 | /// Gets the value of the static field identified by . 48 | /// 49 | public static object Get( this FieldInfo fieldInfo ) 50 | { 51 | return fieldInfo.DelegateForGetFieldValue()( null ); 52 | } 53 | 54 | /// 55 | /// Gets the value of the instance field identified by on the given . 56 | /// 57 | public static object Get( this FieldInfo fieldInfo, object obj ) 58 | { 59 | return fieldInfo.DelegateForGetFieldValue()( obj ); 60 | } 61 | 62 | /// 63 | /// Creates a delegate which can set the value of the field identified by . 64 | /// 65 | public static MemberSetter DelegateForSetFieldValue( this FieldInfo fieldInfo ) 66 | { 67 | var flags = fieldInfo.IsStatic ? Flags.StaticAnyVisibility : Flags.InstanceAnyVisibility; 68 | return (MemberSetter) new MemberSetEmitter( fieldInfo, flags ).GetDelegate(); 69 | } 70 | 71 | /// 72 | /// Creates a delegate which can get the value of the field identified by . 73 | /// 74 | public static MemberGetter DelegateForGetFieldValue( this FieldInfo fieldInfo ) 75 | { 76 | var flags = fieldInfo.IsStatic ? Flags.StaticAnyVisibility : Flags.InstanceAnyVisibility; 77 | return (MemberGetter) new MemberGetEmitter( fieldInfo, flags ).GetDelegate(); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Probing/TypeConverterTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Linq; 23 | using Fasterflect.Probing; 24 | using NUnit.Framework; 25 | using FasterflectTest.SampleModel.Animals.Enumerations; 26 | 27 | namespace FasterflectTest.Probing 28 | { 29 | [TestFixture] 30 | public class TypeConverterTest 31 | { 32 | #region Enum Conversions 33 | [Test] 34 | public void TestConvertFromEnum() 35 | { 36 | Assert.AreEqual( 2, TypeConverter.Get( typeof(int), Climate.Cold ) ); 37 | Assert.AreEqual( 2f, TypeConverter.Get( typeof(float), Climate.Cold ) ); 38 | Assert.AreEqual( 2d, TypeConverter.Get( typeof(double), Climate.Cold ) ); 39 | Assert.AreEqual( "Cold", TypeConverter.Get( typeof(string), Climate.Cold ) ); 40 | } 41 | 42 | [Test] 43 | public void TestConvertToEnum() 44 | { 45 | Assert.AreEqual( Climate.Cold, TypeConverter.Get( typeof(Climate), 2 ) ); 46 | Assert.AreEqual( Climate.Cold, TypeConverter.Get( typeof(Climate), "2" ) ); 47 | Assert.AreEqual( Climate.Cold, TypeConverter.Get( typeof(Climate), "Cold" ) ); 48 | Assert.AreEqual( Climate.Cold, TypeConverter.Get( typeof(Climate), (object) "Cold" ) ); 49 | } 50 | #endregion 51 | 52 | #region Guid Conversions 53 | [Test] 54 | public void TestConvertWithEmptyGuid() 55 | { 56 | string emptyGuidString = string.Empty.PadRight( 16, '\0' ); 57 | string textualGuid = string.Empty.PadRight( 32, '0' ); 58 | var emptyGuidBuffer = new byte[16]; 59 | Assert.AreEqual( Guid.Empty, TypeConverter.Get( typeof(Guid), (object) emptyGuidString ) ); 60 | Assert.AreEqual( Guid.Empty, TypeConverter.Get( typeof(Guid), emptyGuidBuffer ) ); 61 | Assert.AreEqual( Guid.Empty, TypeConverter.Get( typeof(Guid), textualGuid ) ); 62 | } 63 | 64 | [Test] 65 | public void TestConvertWithNonEmptyGuid() 66 | { 67 | Guid guid = Guid.NewGuid(); 68 | string binaryStringGuid = TypeConverter.GuidToBinaryString( guid ); 69 | string readableStringGuid = guid.ToString(); 70 | byte[] binaryGuid = guid.ToByteArray(); 71 | // test direct to guid 72 | Assert.AreEqual( guid, TypeConverter.Get( typeof(Guid), binaryStringGuid ) ); 73 | Assert.AreEqual( guid, TypeConverter.Get( typeof(Guid), readableStringGuid ) ); 74 | Assert.AreEqual( guid, TypeConverter.Get( typeof(Guid), binaryGuid ) ); 75 | // test direct from guid 76 | Assert.AreEqual( binaryStringGuid, TypeConverter.Get( typeof(string), guid ) ); 77 | Assert.IsTrue( binaryGuid.SequenceEqual( (byte[]) TypeConverter.Get( typeof(byte[]), guid ) ) ); 78 | } 79 | #endregion 80 | } 81 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Probing/TryCallMethodValuesOnlyTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Reflection; 23 | using Fasterflect; 24 | using FasterflectTest.SampleModel.Animals; 25 | using NUnit.Framework; 26 | 27 | namespace FasterflectTest.Probing 28 | { 29 | [TestFixture] 30 | public class TryCallMethodValuesOnlyTest 31 | { 32 | // Elephant method overload summary 33 | // 1: public void Eat() 34 | // 2: public void Eat( string food ) 35 | // 3: public void Eat( int count ) 36 | // 4: public void Eat( int count, string food ) 37 | // 5: public void Eat( double count, string food, bool isHay ) 38 | 39 | [Test] 40 | public void TestTryCallWithValuesOnlyAndFixedParameterOrdering() 41 | { 42 | var obj = new Elephant(); 43 | obj.TryCallMethodWithValues("Eat", 1, "foo"); 44 | Assert.AreEqual( 4, obj.MethodInvoked ); 45 | obj.TryCallMethodWithValues("Eat", 1.0, "foo", false); 46 | Assert.AreEqual(5, obj.MethodInvoked); 47 | obj.TryCallMethodWithValues("Eat", "foo"); 48 | Assert.AreEqual(2, obj.MethodInvoked); 49 | obj.TryCallMethodWithValues("Eat", 'f'); 50 | Assert.AreEqual(2, obj.MethodInvoked); 51 | obj.TryCallMethodWithValues("Eat", null); // this invokes 1 and not 2 because null implies the params array parameter is null == no arguments 52 | Assert.AreEqual( 1, obj.MethodInvoked ); 53 | obj.TryCallMethodWithValues("Eat", 1, null); 54 | Assert.AreEqual( 4, obj.MethodInvoked ); 55 | obj.TryCallMethodWithValues("Eat", 1, null, false); 56 | Assert.AreEqual(5, obj.MethodInvoked); 57 | Assert.AreEqual(5, obj.MethodInvoked); 58 | obj.TryCallMethodWithValues("Accept", 'c'); 59 | Assert.AreEqual(12, obj.MethodInvoked); 60 | obj.TryCallMethodWithValues("Accept", "a"); 61 | Assert.AreEqual(12, obj.MethodInvoked); 62 | obj.TryCallMethodWithValues("AcceptParams"); 63 | Assert.AreEqual(13, obj.MethodInvoked); 64 | obj.TryCallMethodWithValues("AcceptParams", null); 65 | Assert.AreEqual(13, obj.MethodInvoked); 66 | obj.TryCallMethodWithValues("AcceptParams", 1); 67 | Assert.AreEqual(13, obj.MethodInvoked); 68 | obj.TryCallMethodWithValues("AcceptParams", 1, "str"); 69 | Assert.AreEqual(13, obj.MethodInvoked); 70 | } 71 | 72 | [Test] 73 | public void TestTryCallWithValuesOnlyAndFixedParameterOrderingOnString() 74 | { 75 | Assert.AreEqual("abc", "abc ".TryCallMethodWithValues("TrimEnd")); 76 | Assert.AreEqual("abc", "abc ".TryCallMethodWithValues("TrimEnd", null)); 77 | Assert.AreEqual("ab", "abc ".TryCallMethodWithValues("TrimEnd", ' ', 'c')); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/People/Person.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System.Collections.Generic; 22 | 23 | namespace FasterflectTest.SampleModel.People 24 | { 25 | public class Person 26 | { 27 | #pragma warning disable 0169, 0649 28 | private static int totalPeopleCreated; 29 | private string name; 30 | private int age; 31 | protected double metersTravelled; 32 | private readonly Dictionary friends; 33 | #pragma warning restore 0169, 0649 34 | 35 | protected static int TotalPeopleCreated 36 | { 37 | get { return totalPeopleCreated; } 38 | set { totalPeopleCreated = value; } 39 | } 40 | 41 | public string Name 42 | { 43 | get { return name; } 44 | set { name = value; } 45 | } 46 | 47 | public int Age 48 | { 49 | get { return age; } 50 | set { age = value; } 51 | } 52 | 53 | private double MetersTravelled 54 | { 55 | get { return metersTravelled; } 56 | set { metersTravelled = value; } 57 | } 58 | 59 | internal Person() : this( string.Empty, 0 ) 60 | { 61 | } 62 | 63 | public Person( Person other ) : this( other.Name, other.Age ) 64 | { 65 | } 66 | 67 | internal Person( string name, int age, out int totalPeopleCreated ) 68 | : this( name, age ) 69 | { 70 | totalPeopleCreated = Person.totalPeopleCreated; 71 | } 72 | 73 | internal Person( string name, int age ) 74 | { 75 | Name = name; 76 | Age = age; 77 | totalPeopleCreated++; 78 | } 79 | 80 | private void Walk( double meters ) 81 | { 82 | this.metersTravelled += meters; 83 | } 84 | 85 | internal void Walk( double meters, out double metersTravelled ) 86 | { 87 | this.metersTravelled += meters; 88 | metersTravelled = this.metersTravelled; 89 | } 90 | 91 | public Person AddFriend( Person friend ) 92 | { 93 | return friend; 94 | } 95 | 96 | public static int GetTotalPeopleCreated() 97 | { 98 | return totalPeopleCreated; 99 | } 100 | 101 | public static int AdjustTotalPeopleCreated( int delta ) 102 | { 103 | totalPeopleCreated += delta; 104 | return totalPeopleCreated; 105 | } 106 | 107 | public Person this[ string name ] 108 | { 109 | get { return friends[ name ]; } 110 | set { friends[ name ] = value; } 111 | } 112 | 113 | public Person this[ string name, int age ] 114 | { 115 | get 116 | { 117 | var person = friends[ name ]; 118 | return person == null 119 | ? null 120 | : person.Age == age 121 | ? person 122 | : null; 123 | } 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/BaseEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | using System.Reflection.Emit; 22 | using Fasterflect.Caching; 23 | 24 | namespace Fasterflect.Emitter 25 | { 26 | internal abstract class BaseEmitter 27 | { 28 | private static readonly Cache cache = new Cache(); 29 | 30 | 31 | protected static readonly MethodInfo StructGetMethod = 32 | Constants.StructType.GetTypeInfo().GetMethod( "get_Value", BindingFlags.Public | BindingFlags.Instance ); 33 | 34 | 35 | protected static readonly MethodInfo StructSetMethod = 36 | Constants.StructType.GetTypeInfo().GetMethod( "set_Value", BindingFlags.Public | BindingFlags.Instance ); 37 | 38 | protected CallInfo CallInfo; 39 | protected DynamicMethod Method; 40 | protected EmitHelper Generator; 41 | 42 | protected BaseEmitter( CallInfo callInfo ) 43 | { 44 | CallInfo = callInfo; 45 | } 46 | 47 | internal Delegate GetDelegate() 48 | { 49 | var action = cache.Get( CallInfo ); 50 | if( action == null ) 51 | { 52 | Method = CreateDynamicMethod(); 53 | Generator = new EmitHelper( Method.GetILGenerator() ); 54 | action = CreateDelegate(); 55 | cache.Insert( CallInfo, action, CacheStrategy.Temporary ); 56 | } 57 | return action; 58 | } 59 | 60 | protected internal abstract DynamicMethod CreateDynamicMethod(); 61 | protected internal abstract Delegate CreateDelegate(); 62 | 63 | protected internal static DynamicMethod CreateDynamicMethod( string name, Type targetType, Type returnType, 64 | Type[] paramTypes ) 65 | { 66 | return new DynamicMethod( name, MethodAttributes.Static | MethodAttributes.Public, 67 | CallingConventions.Standard, returnType, paramTypes, 68 | targetType.IsArray ? targetType.GetElementType() : targetType, 69 | true ); 70 | } 71 | 72 | protected void LoadInnerStructToLocal( byte localPosition ) 73 | { 74 | Generator 75 | .castclass( Constants.StructType ) // (ValueTypeHolder)wrappedStruct 76 | .callvirt( StructGetMethod ) // .get_Value() 77 | .unbox_any( CallInfo.TargetType ) // unbox 78 | .stloc( localPosition ) // localStr = 79 | .ldloca_s( localPosition ); // load &localStr 80 | } 81 | 82 | protected void StoreLocalToInnerStruct( byte localPosition ) 83 | { 84 | StoreLocalToInnerStruct( 0, localPosition ); // 0: 'this' 85 | } 86 | 87 | protected void StoreLocalToInnerStruct( byte argPosition, byte localPosition ) 88 | { 89 | Generator 90 | .ldarg( argPosition ) 91 | .castclass( Constants.StructType ) // wrappedStruct = (ValueTypeHolder)this 92 | .ldloc( localPosition ) // load localStr 93 | .boxIfValueType( CallInfo.TargetType ) // box 94 | .callvirt( StructSetMethod ); // wrappedStruct.set_Value() 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Probing/MethodDispatcherTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using System.Linq; 24 | using System.Xml.Linq; 25 | using Fasterflect; 26 | using Fasterflect.Probing; 27 | using FasterflectTest.SampleModel.Animals; 28 | using NUnit.Framework; 29 | 30 | namespace FasterflectTest.Probing 31 | { 32 | [TestFixture] 33 | public class MethodDispatcherTest 34 | { 35 | [Test] 36 | public void TestMethodDispatcherWithSingleMethod() 37 | { 38 | var obj = new Elephant(); 39 | var dispatcher = new MethodDispatcher(); 40 | dispatcher.AddMethod( typeof(Elephant).Methods( "Eat" ).First() ); 41 | dispatcher.Invoke( obj, true, new {} ); 42 | Assert.AreEqual( 1, obj.MethodInvoked ); 43 | } 44 | 45 | [Test] 46 | public void TestMethodDispatcherWithMultipleMethods() 47 | { 48 | var obj = new Elephant(); 49 | var dispatcher = new MethodDispatcher(); 50 | typeof(Elephant).Methods( Flags.InstanceAnyVisibility | Flags.ExcludeBackingMembers ).ForEach( dispatcher.AddMethod ); 51 | dispatcher.Invoke( obj, true, new {} ); 52 | Assert.AreEqual( 1, obj.MethodInvoked ); 53 | dispatcher.Invoke( obj, true, new { count=2.0, food="hay", isHay=true } ); 54 | Assert.AreEqual( 5, obj.MethodInvoked ); 55 | dispatcher.Invoke( obj, true, new { count=2, volume=4 } ); 56 | Assert.AreEqual( 11, obj.MethodInvoked ); 57 | } 58 | 59 | #region Sample class with static overloads 60 | internal class StaticElephant 61 | { 62 | #pragma warning disable 0169, 0649 63 | public static int MethodInvoked { get; private set; } 64 | #pragma warning restore 0169, 0649 65 | 66 | public static void Eat() 67 | { 68 | MethodInvoked = 1; 69 | } 70 | public static void Eat( string food ) 71 | { 72 | MethodInvoked = 2; 73 | } 74 | public static void Eat( int count ) 75 | { 76 | MethodInvoked = 3; 77 | } 78 | public static void Eat( int count, string food ) 79 | { 80 | MethodInvoked = 4; 81 | } 82 | public static void Eat( double count, string food, bool isHay ) 83 | { 84 | MethodInvoked = 5; 85 | } 86 | } 87 | #endregion 88 | 89 | [Test] 90 | public void TestMethodDispatcherWithStaticMethods() 91 | { 92 | var type = typeof(StaticElephant); 93 | var dispatcher = new MethodDispatcher(); 94 | typeof(StaticElephant).Methods( Flags.StaticAnyVisibility ).ForEach( dispatcher.AddMethod ); 95 | dispatcher.Invoke( type, true, new {} ); 96 | Assert.AreEqual( 1, StaticElephant.MethodInvoked ); 97 | dispatcher.Invoke( type, true, new { count=2.0, food="hay", isHay=true } ); 98 | Assert.AreEqual( 5, StaticElephant.MethodInvoked ); 99 | dispatcher.Invoke( type, false, new { count=2, volume=4 } ); 100 | Assert.AreEqual( 3, StaticElephant.MethodInvoked ); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/IndexerTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Linq; 23 | using Fasterflect; 24 | using FasterflectTest.SampleModel.People; 25 | using NUnit.Framework; 26 | 27 | namespace FasterflectTest.Invocation 28 | { 29 | [TestFixture] 30 | public class IndexerTest : BaseInvocationTest 31 | { 32 | [Test] 33 | public void TestInvokeOneArgIndexer() 34 | { 35 | InvokeIndexer( ( person, sample ) => person.GetIndexer( sample[ 0 ] ) ); 36 | } 37 | 38 | [Test] 39 | public void TestInvokeTwoArgsIndexer() 40 | { 41 | InvokeIndexer( ( person, sample ) => person.GetIndexer( sample[ 0 ], sample[ 1 ] ) ); 42 | } 43 | 44 | private void InvokeIndexer( Func getIndexerAction ) 45 | { 46 | RunWith( ( personBase, elementType, elementTypeNullable ) => 47 | { 48 | var people = new[] { new object[] { "John", 10 }, new object[] { "Jane", 20 } }; 49 | people.ForEach( sample => 50 | { 51 | var person = elementType.CreateInstance( sample[ 0 ], sample[ 1 ] ); 52 | var name = person.WrapIfValueType().GetFieldValue( "name" ); 53 | personBase.SetIndexer( new[] { typeof(string), elementTypeNullable }, name, 54 | person ); 55 | } ); 56 | people.ForEach( sample => 57 | { 58 | var person = getIndexerAction( personBase, sample ); 59 | VerifyFields( person.WrapIfValueType(), 60 | new { name = sample[ 0 ], age = sample[ 1 ] } ); 61 | } ); 62 | } ); 63 | } 64 | 65 | private void RunWith( Action assertionAction ) 66 | { 67 | Types.Select( t => 68 | { 69 | var emptyDictionary = t.Field( "friends" ).FieldType.CreateInstance(); 70 | var person = t.CreateInstance().WrapIfValueType(); 71 | person.SetFieldValue( "friends", emptyDictionary ); 72 | return person; 73 | } ).ForEach( 74 | person => 75 | assertionAction( 76 | person, 77 | !person.IsWrapped() ? typeof(Person) : typeof(PersonStruct), 78 | person is Person ? typeof(Person) : typeof(PersonStruct?) ) ); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/CtorInvocationEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Reflection; 23 | using System.Reflection.Emit; 24 | 25 | namespace Fasterflect.Emitter 26 | { 27 | internal class CtorInvocationEmitter : InvocationEmitter 28 | { 29 | public CtorInvocationEmitter(ConstructorInfo ctorInfo, Flags bindingFlags) 30 | : this(ctorInfo.DeclaringType, bindingFlags, ctorInfo.GetParameters().ToTypeArray(), ctorInfo) { } 31 | 32 | public CtorInvocationEmitter(Type targetType, Flags bindingFlags, Type[] paramTypes) 33 | : this(targetType, bindingFlags, paramTypes, null) { } 34 | 35 | private CtorInvocationEmitter(Type targetType, Flags flags, Type[] parameterTypes, ConstructorInfo ctorInfo) 36 | : base(new CallInfo(targetType, null, flags, MemberTypes.Constructor, targetType.Name, parameterTypes, ctorInfo, true)) 37 | { 38 | } 39 | 40 | protected internal override DynamicMethod CreateDynamicMethod() 41 | { 42 | return CreateDynamicMethod("ctor", CallInfo.TargetType, Constants.ObjectType, new[] { Constants.ObjectType }); 43 | } 44 | 45 | protected internal override Delegate CreateDelegate() 46 | { 47 | if (CallInfo.IsTargetTypeStruct && CallInfo.HasNoParam) // no-arg struct needs special initialization 48 | { 49 | Generator.DeclareLocal( CallInfo.TargetType ); // TargetType tmp 50 | Generator.ldloca_s(0) // &tmp 51 | .initobj( CallInfo.TargetType ) // init_obj(&tmp) 52 | .ldloc_0.end(); // load tmp 53 | } 54 | else if (CallInfo.TargetType.IsArray) 55 | { 56 | Generator.ldarg_0 // load args[] (method arguments) 57 | .ldc_i4_0 // load 0 58 | .ldelem_ref // load args[0] (length) 59 | .unbox_any( typeof(int) ) // unbox stack 60 | .newarr( CallInfo.TargetType.GetElementType() ); // new T[args[0]] 61 | } 62 | else 63 | { 64 | ConstructorInfo ctorInfo = LookupUtils.GetConstructor(CallInfo); 65 | byte startUsableLocalIndex = 0; 66 | if (CallInfo.HasRefParam) 67 | { 68 | startUsableLocalIndex = CreateLocalsForByRefParams(0, ctorInfo); // create by_ref_locals from argument array 69 | Generator.DeclareLocal(CallInfo.TargetType); // TargetType tmp; 70 | } 71 | 72 | PushParamsOrLocalsToStack(0); // push arguments and by_ref_locals 73 | Generator.newobj(ctorInfo); // ctor () 74 | 75 | if (CallInfo.HasRefParam) 76 | { 77 | Generator.stloc(startUsableLocalIndex); // tmp = ; 78 | AssignByRefParamsToArray(0); // store by_ref_locals back to argument array 79 | Generator.ldloc(startUsableLocalIndex); // tmp 80 | } 81 | } 82 | Generator.boxIfValueType(CallInfo.TargetType) 83 | .ret(); // return (box); 84 | return Method.CreateDelegate(typeof (ConstructorInvoker)); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/GenericTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Fasterflect; 4 | using System.Collections.Generic; 5 | using Fasterflect.Emitter; 6 | using NUnit.Framework; 7 | 8 | namespace FasterflectTest.Invocation 9 | { 10 | [TestFixture] 11 | public class GenericTest 12 | { 13 | [Test] 14 | public void Test_instantiate_generic_types() 15 | { 16 | object list = typeof(List<>).MakeGenericType( typeof(string) ).CreateInstance(); 17 | Assert.IsInstanceOfType(typeof(List), list); 18 | 19 | object dict = typeof(Dictionary<,>).MakeGenericType( typeof(string), typeof(int) ).CreateInstance(); 20 | Assert.IsInstanceOfType(typeof(Dictionary), dict); 21 | } 22 | 23 | private class Host 24 | { 25 | public static T Exact( T t ) 26 | { 27 | return t; 28 | } 29 | 30 | public string Add( T1 obj1, T2 obj2 ) 31 | { 32 | return string.Format( "1:{0}{1}", obj1, obj2 ); 33 | } 34 | 35 | public string Add( T1 obj1, T2 obj2, T2 obj3 ) 36 | { 37 | return string.Format( "2:{0}{1}{2}", obj1, obj2, obj3 ); 38 | } 39 | 40 | public string Add( T1 obj1, int obj2 ) 41 | { 42 | return string.Format( "3:{0}{1}", obj1, obj2 ); 43 | } 44 | 45 | public string Add( T1 obj1, int obj2, T1 obj3 ) 46 | { 47 | return string.Format( "4:{0}{1}{2}", obj1, obj2, obj3 ); 48 | } 49 | 50 | public string Add( T1 obj1 ) 51 | { 52 | return string.Format( "5:{0}_{1}", obj1, typeof(T2).Name ); 53 | } 54 | 55 | public string Add( object obj1, object obj2 ) 56 | { 57 | return string.Format( "6:{0}{1}", obj1, obj2 ); 58 | } 59 | } 60 | 61 | [Test] 62 | public void Test_invoke_static_generic_methods() 63 | { 64 | Type type = typeof(Host); 65 | var val = (int) type.CallMethod( new[] { typeof(int) }, "Exact", 1 ); 66 | Assert.AreEqual( 1, val ); 67 | } 68 | 69 | [Test] 70 | public void Test_invoke_instance_generic_method_two_arguments_two_params() 71 | { 72 | object target = typeof(Host).CreateInstance(); 73 | var result = (string) target.CallMethod( new[] { typeof(string), typeof(int) }, "Add", "1", 2 ); 74 | Assert.AreEqual( "1:12", result ); 75 | } 76 | 77 | [Test] 78 | public void Test_invoke_instance_generic_method_two_arguments_three_params() 79 | { 80 | object target = typeof(Host).CreateInstance(); 81 | var result = (string) target.CallMethod( new[] { typeof(string), typeof(int) }, "Add", "1", 2, 3 ); 82 | Assert.AreEqual( "2:123", result ); 83 | } 84 | 85 | [Test] 86 | public void Test_invoke_instance_generic_method_one_argument_two_params_one_generic() 87 | { 88 | object target = typeof(Host).CreateInstance(); 89 | var result = (string) target.CallMethod( new[] { typeof(string) }, "Add", "1", 2 ); 90 | Assert.AreEqual( "3:12", result ); 91 | } 92 | 93 | [Test] 94 | public void Test_invoke_instance_generic_method_one_argument_three_params_two_generic() 95 | { 96 | object target = typeof(Host).CreateInstance(); 97 | var result = (string) target.CallMethod( new[] { typeof(string) }, "Add", "1", 2, "3" ); 98 | Assert.AreEqual( "4:123", result ); 99 | } 100 | 101 | [Test] 102 | public void Test_invoke_instance_generic_method_two_arguments_one_param_generic() 103 | { 104 | object target = typeof(Host).CreateInstance(); 105 | var result = (string) target.CallMethod( new[] { typeof(string), typeof(int) }, "Add", "1" ); 106 | Assert.AreEqual( "5:1_Int32", result ); 107 | } 108 | 109 | [Test] 110 | public void Test_invoke_instance_non_generic_method_two_params() 111 | { 112 | object target = typeof(Host).CreateInstance(); 113 | var result = (string) target.CallMethod( null, "Add", "1", 2 ); 114 | Assert.AreEqual( "6:12", result ); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/MemberSetEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Reflection; 23 | using System.Reflection.Emit; 24 | 25 | namespace Fasterflect.Emitter 26 | { 27 | internal class MemberSetEmitter : BaseEmitter 28 | { 29 | public MemberSetEmitter(MemberInfo memberInfo, Flags bindingFlags) 30 | : this(memberInfo.DeclaringType, bindingFlags, memberInfo.MemberType, memberInfo.Name, memberInfo) 31 | { 32 | } 33 | 34 | public MemberSetEmitter(Type targetType, Flags bindingFlags, MemberTypes memberType, string fieldOrProperty) 35 | : this(targetType, bindingFlags, memberType, fieldOrProperty, null) 36 | { 37 | } 38 | 39 | private MemberSetEmitter(Type targetType, Flags bindingFlags, MemberTypes memberType, string fieldOrProperty, MemberInfo memberInfo) 40 | : base(new CallInfo(targetType, null, bindingFlags, memberType, fieldOrProperty, Constants.ArrayOfObjectType, memberInfo, false)) 41 | { 42 | } 43 | internal MemberSetEmitter(CallInfo callInfo) : base(callInfo) 44 | { 45 | } 46 | 47 | protected internal override DynamicMethod CreateDynamicMethod() 48 | { 49 | return CreateDynamicMethod("setter", CallInfo.TargetType, null, new[] { Constants.ObjectType, Constants.ObjectType }); 50 | } 51 | 52 | protected internal override Delegate CreateDelegate() 53 | { 54 | MemberInfo member = CallInfo.MemberInfo; 55 | if( member == null ) 56 | { 57 | member = LookupUtils.GetMember( CallInfo ); 58 | CallInfo.IsStatic = member.IsStatic(); 59 | } 60 | bool handleInnerStruct = CallInfo.ShouldHandleInnerStruct; 61 | 62 | if( CallInfo.IsStatic ) 63 | { 64 | Generator.ldarg_1.end(); // load value-to-be-set 65 | } 66 | else 67 | { 68 | Generator.ldarg_0.end(); // load arg-0 (this) 69 | if (handleInnerStruct) 70 | { 71 | Generator.DeclareLocal(CallInfo.TargetType); // TargetType tmpStr 72 | LoadInnerStructToLocal(0); // tmpStr = ((ValueTypeHolder)this)).Value; 73 | Generator.ldarg_1.end(); // load value-to-be-set; 74 | } 75 | else 76 | { 77 | Generator.castclass( CallInfo.TargetType ) // (TargetType)this 78 | .ldarg_1.end(); // load value-to-be-set; 79 | } 80 | } 81 | 82 | Generator.CastFromObject( member.Type() ); // unbox | cast value-to-be-set 83 | if (member.MemberType == MemberTypes.Field) 84 | { 85 | var field = member as FieldInfo; 86 | Generator.stfld(field.IsStatic, field); // (this|tmpStr).field = value-to-be-set; 87 | } 88 | else 89 | { 90 | var prop = member as PropertyInfo; 91 | MethodInfo setMethod = LookupUtils.GetPropertySetMethod(prop, CallInfo); 92 | Generator.call(setMethod.IsStatic || CallInfo.IsTargetTypeStruct, setMethod); // (this|tmpStr).set_Prop(value-to-be-set); 93 | } 94 | 95 | if (handleInnerStruct) 96 | { 97 | StoreLocalToInnerStruct(0); // ((ValueTypeHolder)this)).Value = tmpStr 98 | } 99 | 100 | Generator.ret(); 101 | 102 | return Method.CreateDelegate(typeof (MemberSetter)); 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/SampleModel/People/PersonStruct.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System.Collections.Generic; 22 | 23 | namespace FasterflectTest.SampleModel.People 24 | { 25 | public struct PersonStruct 26 | { 27 | #pragma warning disable 0169, 0649 28 | private static int totalPeopleCreated; 29 | private string name; 30 | private int age; 31 | private double metersTravelled; 32 | private readonly Dictionary friends; 33 | #pragma warning restore 0169, 0649 34 | 35 | public static int TotalPeopleCreated 36 | { 37 | get { return totalPeopleCreated; } 38 | set { totalPeopleCreated = value; } 39 | } 40 | 41 | public string Name 42 | { 43 | get { return name; } 44 | set { name = value; } 45 | } 46 | 47 | public int Age 48 | { 49 | get { return age; } 50 | set { age = value; } 51 | } 52 | 53 | public double MetersTravelled 54 | { 55 | get { return metersTravelled; } 56 | set { metersTravelled = value; } 57 | } 58 | 59 | internal PersonStruct( PersonStruct other ) : this( other.Name, other.Age ) 60 | { 61 | } 62 | 63 | internal PersonStruct( string name, int age, out int totalPeopleCreated ) 64 | : this( name, age ) 65 | { 66 | totalPeopleCreated = PersonStruct.totalPeopleCreated; 67 | } 68 | 69 | internal PersonStruct( string name, int age ) : this() 70 | { 71 | this.name = name; 72 | this.age = age; 73 | totalPeopleCreated++; 74 | } 75 | 76 | private void Walk( double meters ) 77 | { 78 | this.metersTravelled += meters; 79 | } 80 | 81 | internal void Walk( double meters, out double metersTravelled ) 82 | { 83 | this.metersTravelled += meters; 84 | metersTravelled = this.metersTravelled; 85 | } 86 | 87 | public PersonStruct AddFriend( PersonStruct friend ) 88 | { 89 | return friend; 90 | } 91 | 92 | public static int GetTotalPeopleCreated() 93 | { 94 | return totalPeopleCreated; 95 | } 96 | 97 | public static int AdjustTotalPeopleCreated( int delta ) 98 | { 99 | totalPeopleCreated += delta; 100 | return totalPeopleCreated; 101 | } 102 | 103 | public PersonStruct? this[ string name ] 104 | { 105 | get { return friends[ name ]; } 106 | set { friends[ name ] = value; } 107 | } 108 | 109 | public PersonStruct? this[ string name, int age ] 110 | { 111 | get 112 | { 113 | var person = friends[ name ]; 114 | return person == null 115 | ? null 116 | : person.Value.Age == age 117 | ? person 118 | : null; 119 | } 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/ParameterInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.ComponentModel; 21 | using System.Reflection; 22 | 23 | namespace Fasterflect 24 | { 25 | /// 26 | /// Extension methods for inspecting and working with method parameters. 27 | /// 28 | public static class ParameterInfoExtensions 29 | { 30 | /// 31 | /// Determines whether null can be assigned to the given . 32 | /// 33 | /// True if null can be assigned, false otherwise. 34 | public static bool IsNullable( this ParameterInfo parameter ) 35 | { 36 | return ! parameter.ParameterType.GetTypeInfo().IsValueType || parameter.ParameterType.GetTypeInfo().IsSubclassOf( typeof(Nullable) ); 37 | } 38 | 39 | /// 40 | /// Determines whether the given has the given . 41 | /// The comparison uses OrdinalIgnoreCase and allows for a leading underscore in either name 42 | /// to be ignored. 43 | /// 44 | /// True if the name is considered identical, false otherwise. If either parameter 45 | /// is null an exception will be thrown. 46 | public static bool HasName( this ParameterInfo parameter, string name ) 47 | { 48 | string parameterName = parameter.Name.Length > 0 && parameter.Name[ 0 ] == '_' 49 | ? parameter.Name.Substring( 1 ) 50 | : parameter.Name; 51 | name = name.Length > 0 && name[ 0 ] == '_' ? name.Substring( 1 ) : name; 52 | return parameterName.Equals( name, StringComparison.OrdinalIgnoreCase ); 53 | } 54 | 55 | /// 56 | /// Determines whether the given has an associated default value as 57 | /// supplied by an . This method does not read the value of 58 | /// the attribute. It also does not support C# 4.0 default parameter specifications. 59 | /// 60 | /// True if the attribute was detected, false otherwise. 61 | public static bool HasDefaultValue( this ParameterInfo parameter ) 62 | { 63 | var defaultValue = parameter.Attribute(); 64 | return defaultValue != null; 65 | } 66 | 67 | /// 68 | /// Gets the default value associated with the given . The value is 69 | /// obtained from the if present on the parameter. This method 70 | /// does not support C# 4.0 default parameter specifications. 71 | /// 72 | /// The default value if one could be obtained and converted into the type of the parameter, 73 | /// and null otherwise. 74 | public static object DefaultValue( this ParameterInfo parameter ) 75 | { 76 | var defaultValue = parameter.Attribute(); 77 | return defaultValue != null 78 | ? Probing.TypeConverter.Get( parameter.ParameterType, defaultValue.Value ) 79 | : null; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Common/Delegates.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | namespace Fasterflect 20 | { 21 | /// 22 | /// A delegate to retrieve the value of an instance field or property of an object. 23 | /// 24 | /// 25 | /// The object whose field's or property's value is to be retrieved. 26 | /// Use null for static field or property. 27 | /// 28 | /// The value of the instance field or property. 29 | public delegate object MemberGetter( object obj ); 30 | 31 | /// 32 | /// A delegate to set the value of an instance field or property of an object. 33 | /// 34 | /// 35 | /// The object whose field's or property's value is to be set. 36 | /// Use null for static field or property. 37 | /// 38 | /// The value to be set to the field or property. 39 | public delegate void MemberSetter( object obj, object value ); 40 | 41 | /// 42 | /// A delegate to set an element of an array. 43 | /// 44 | /// The array whose element is to be set. 45 | /// The index of the element to be set. 46 | /// The value to set to the element. 47 | public delegate void ArrayElementSetter( object array, int index, object value ); 48 | 49 | /// 50 | /// A delegate to retrieve an element of an array. 51 | /// 52 | /// The array whose element is to be retrieved 53 | /// The index of the element to be retrieved 54 | /// The element at 55 | public delegate object ArrayElementGetter( object array, int index ); 56 | 57 | /// 58 | /// A delegate to invoke an instance method or indexer of an object. 59 | /// 60 | /// 61 | /// The object whose method or indexer is to be invoked on. 62 | /// Use null for static method. 63 | /// The properly-ordered parameter list of the method/indexer. 64 | /// For indexer-set operation, the parameter array include parameters for the indexer plus 65 | /// the value to be set to the indexer. 66 | /// The return value of the method or indexer. Null is returned if the method has no 67 | /// return type or if it's a indexer-set operation. 68 | public delegate object MethodInvoker( object obj, params object[] parameters ); 69 | 70 | /// 71 | /// A delegate to invoke the constructor of a type. 72 | /// 73 | /// The properly-ordered parameter list of the constructor. 74 | /// An instance of type whose constructor is invoked. 75 | public delegate object ConstructorInvoker( params object[] parameters ); 76 | 77 | /// 78 | /// A delegate to copy values of instance members (fields, properties, or both) from one object to another. 79 | /// 80 | /// The object whose instance members' values will be read. 81 | /// The object whose instance members' values will be written. 82 | public delegate void ObjectMapper( object source, object target ); 83 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/PropertyInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System.Reflection; 20 | using Fasterflect.Emitter; 21 | 22 | namespace Fasterflect 23 | { 24 | /// 25 | /// Extension methods for inspecting and working with properties. 26 | /// 27 | public static class PropertyInfoExtensions 28 | { 29 | /// 30 | /// Sets the static property identified by to the specified . 31 | /// 32 | public static void Set( this PropertyInfo propInfo, object value ) 33 | { 34 | propInfo.DelegateForSetPropertyValue( Flags.StaticAnyVisibility )( null, value ); 35 | } 36 | 37 | /// 38 | /// Sets the instance property identified by on the given 39 | /// to the specified . 40 | /// 41 | public static void Set( this PropertyInfo propInfo, object obj, object value ) 42 | { 43 | propInfo.DelegateForSetPropertyValue( Flags.InstanceAnyVisibility )( obj, value ); 44 | } 45 | 46 | /// 47 | /// Gets the value of the static property identified by . 48 | /// 49 | public static object Get( this PropertyInfo propInfo ) 50 | { 51 | return propInfo.DelegateForGetPropertyValue( Flags.StaticAnyVisibility )( null ); 52 | } 53 | 54 | /// 55 | /// Gets the value of the instance property identified by on the given . 56 | /// 57 | public static object Get( this PropertyInfo propInfo, object obj ) 58 | { 59 | return propInfo.DelegateForGetPropertyValue( Flags.InstanceAnyVisibility )( obj ); 60 | } 61 | 62 | /// 63 | /// Creates a delegate which can set the value of the property . 64 | /// 65 | public static MemberSetter DelegateForSetPropertyValue( this PropertyInfo propInfo ) 66 | { 67 | var flags = propInfo.IsStatic() ? Flags.StaticAnyVisibility : Flags.InstanceAnyVisibility; 68 | return (MemberSetter) new MemberSetEmitter( propInfo, flags ).GetDelegate(); 69 | } 70 | 71 | /// 72 | /// Creates a delegate which can set the value of the property matching the 73 | /// specified . 74 | /// 75 | public static MemberSetter DelegateForSetPropertyValue( this PropertyInfo propInfo, Flags bindingFlags ) 76 | { 77 | return (MemberSetter) new MemberSetEmitter( propInfo, bindingFlags ).GetDelegate(); 78 | } 79 | 80 | /// 81 | /// Creates a delegate which can get the value of the property . 82 | /// 83 | public static MemberGetter DelegateForGetPropertyValue( this PropertyInfo propInfo ) 84 | { 85 | var flags = propInfo.IsStatic() ? Flags.StaticAnyVisibility : Flags.InstanceAnyVisibility; 86 | return (MemberGetter) new MemberGetEmitter( propInfo, flags ).GetDelegate(); 87 | } 88 | 89 | /// 90 | /// Creates a delegate which can get the value of the property matching the 91 | /// specified . 92 | /// 93 | public static MemberGetter DelegateForGetPropertyValue( this PropertyInfo propInfo, Flags bindingFlags ) 94 | { 95 | return (MemberGetter) new MemberGetEmitter( propInfo, bindingFlags ).GetDelegate(); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/MemberGetEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Reflection; 23 | using System.Reflection.Emit; 24 | 25 | namespace Fasterflect.Emitter 26 | { 27 | internal class MemberGetEmitter : BaseEmitter 28 | { 29 | public MemberGetEmitter( MemberInfo memberInfo, Flags bindingFlags ) 30 | : this( memberInfo.DeclaringType, bindingFlags, memberInfo.MemberType, memberInfo.Name, memberInfo ) 31 | { 32 | } 33 | 34 | public MemberGetEmitter( Type targetType, Flags bindingFlags, MemberTypes memberType, string fieldOrPropertyName ) 35 | : this( targetType, bindingFlags, memberType, fieldOrPropertyName, null ) 36 | { 37 | } 38 | 39 | private MemberGetEmitter( Type targetType, Flags bindingFlags, MemberTypes memberType, string fieldOrPropertyName, MemberInfo memberInfo ) 40 | : base(new CallInfo(targetType, null, bindingFlags, memberType, fieldOrPropertyName, Type.EmptyTypes, memberInfo, true)) 41 | { 42 | } 43 | internal MemberGetEmitter( CallInfo callInfo ) : base( callInfo ) 44 | { 45 | } 46 | 47 | protected internal override DynamicMethod CreateDynamicMethod() 48 | { 49 | return CreateDynamicMethod("getter", CallInfo.TargetType, Constants.ObjectType, new[] { Constants.ObjectType }); 50 | } 51 | 52 | protected internal override Delegate CreateDelegate() 53 | { 54 | MemberInfo member = CallInfo.MemberInfo; 55 | if( member == null ) 56 | { 57 | member = LookupUtils.GetMember( CallInfo ); 58 | CallInfo.IsStatic = member.IsStatic(); 59 | } 60 | bool handleInnerStruct = CallInfo.ShouldHandleInnerStruct; 61 | 62 | if (handleInnerStruct) 63 | { 64 | Generator.ldarg_0 // load arg-0 (this) 65 | .DeclareLocal(CallInfo.TargetType); // TargetType tmpStr 66 | LoadInnerStructToLocal(0); // tmpStr = ((ValueTypeHolder)this)).Value 67 | Generator.DeclareLocal(Constants.ObjectType); // object result; 68 | } 69 | else if (!CallInfo.IsStatic) 70 | { 71 | Generator.ldarg_0 // load arg-0 (this) 72 | .castclass( CallInfo.TargetType ); // (TargetType)this 73 | } 74 | 75 | if (member.MemberType == MemberTypes.Field) 76 | { 77 | var field = member as FieldInfo; 78 | 79 | if( field.DeclaringType.GetTypeInfo().IsEnum ) // special enum handling as ldsfld does not support enums 80 | { 81 | Generator.ldc_i4( (int) field.GetValue( field.DeclaringType ) ) 82 | .boxIfValueType( field.FieldType ); 83 | } 84 | else 85 | { 86 | Generator.ldfld( field.IsStatic, field ) // (this|tmpStr).field OR TargetType.field 87 | .boxIfValueType( field.FieldType ); // (object) 88 | } 89 | } 90 | else 91 | { 92 | var prop = member as PropertyInfo; 93 | MethodInfo getMethod = LookupUtils.GetPropertyGetMethod(prop, CallInfo); 94 | Generator.call(getMethod.IsStatic || CallInfo.IsTargetTypeStruct, getMethod ) // (this|tmpStr).prop OR TargetType.prop 95 | .boxIfValueType(prop.PropertyType); // (object) 96 | } 97 | 98 | if (handleInnerStruct) 99 | { 100 | Generator.stloc_1.end(); // resultLocal = 101 | StoreLocalToInnerStruct(0); // ((ValueTypeHolder)this)).Value = tmpStr 102 | Generator.ldloc_1.end(); // push resultLocal 103 | } 104 | 105 | Generator.ret(); 106 | 107 | return Method.CreateDelegate(typeof (MemberGetter)); 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/DelegateCacheTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Collections; 23 | using Fasterflect; 24 | using Fasterflect.Emitter; 25 | using FasterflectTest.SampleModel.People; 26 | using NUnit.Framework; 27 | 28 | namespace FasterflectTest.Invocation 29 | { 30 | [TestFixture] 31 | public class DelegateCacheTest : BaseInvocationTest 32 | { 33 | private readonly object[] objectTypes = { 34 | typeof(Person).CreateInstance(), 35 | typeof(PersonStruct).CreateInstance().WrapIfValueType() 36 | }; 37 | 38 | private void ExecuteCacheTest( params Action[] actions ) 39 | { 40 | IDictionary delegateMap = (IDictionary)typeof(BaseEmitter).GetFieldValue("cache").GetFieldValue("entries"); 41 | delegateMap.Clear(); 42 | 43 | int delCount = delegateMap.Count; 44 | foreach( var action in actions ) 45 | { 46 | for( int i = 0; i < 20; i++ ) 47 | { 48 | action(); 49 | } 50 | Assert.AreEqual( ++delCount, delegateMap.Count ); 51 | } 52 | } 53 | 54 | [Test] 55 | public void TestDelegateIsProperlyCachedForFields() 56 | { 57 | objectTypes.ForEach( 58 | obj => 59 | ExecuteCacheTest( 60 | () => obj.SetFieldValue( "name", "John" ), 61 | () => obj.GetFieldValue( "age" ) ) ); 62 | Types.ForEach( type => ExecuteCacheTest( 63 | () => type.SetFieldValue( "totalPeopleCreated", 1 ), 64 | () => type.GetFieldValue( "totalPeopleCreated" ) ) ); 65 | } 66 | 67 | [Test] 68 | public void TestDelegateIsProperlyCachedForProperties() 69 | { 70 | objectTypes.ForEach( 71 | obj => 72 | ExecuteCacheTest( 73 | () => 74 | obj.SetPropertyValue( "Name", "John" ), 75 | () => obj.GetPropertyValue( "Age" ) ) ); 76 | Types.ForEach( type => ExecuteCacheTest( 77 | () => type.SetPropertyValue( "TotalPeopleCreated", 1 ), 78 | () => type.GetPropertyValue( "TotalPeopleCreated" ) ) ); 79 | } 80 | 81 | [Test] 82 | public void TestDelegateIsProperlyCachedForConstructors() 83 | { 84 | RunWith( ( Type type ) => ExecuteCacheTest( 85 | () => type.CreateInstance(), 86 | () => type.CreateInstance( "John", 10 ) ) ); 87 | } 88 | 89 | [Test] 90 | public void TestDelegateIsProperlyCachedForMethods() 91 | { 92 | var arguments = new object[] { 100d, null }; 93 | objectTypes.ForEach( 94 | obj => 95 | ExecuteCacheTest( () => obj.CallMethod( "Walk", 100d ), 96 | () => obj.CallMethod( "Walk", 97 | new[] 98 | { 99 | typeof(double), typeof(double).MakeByRefType() 100 | }, arguments ) ) ); 101 | Types.ForEach( type => ExecuteCacheTest( 102 | () => type.CallMethod( "GetTotalPeopleCreated" ), 103 | () => type.CallMethod( "AdjustTotalPeopleCreated", 10 ) ) ); 104 | } 105 | 106 | [Test] 107 | public void TestDelegateIsProperlyCachedForIndexers() 108 | { 109 | for( int i = 0; i < Types.Length; i++ ) 110 | { 111 | var emptyDictionary = Types[ i ].Field( "friends" ).FieldType.CreateInstance(); 112 | objectTypes[ i ].SetFieldValue( "friends", emptyDictionary ); 113 | ExecuteCacheTest( () => objectTypes[ i ].SetIndexer( 114 | new[] 115 | { 116 | typeof(string), 117 | Types[ i ] == typeof(Person) 118 | ? typeof(Person) 119 | : typeof(PersonStruct?) 120 | }, 121 | "John", null ), 122 | () => objectTypes[ i ].GetIndexer( "John" ), 123 | () => objectTypes[ i ].GetIndexer( "John", 10 ) ); 124 | } 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/MethodInvocationEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | using System.Reflection.Emit; 22 | 23 | namespace Fasterflect.Emitter 24 | { 25 | internal class MethodInvocationEmitter : InvocationEmitter 26 | { 27 | public MethodInvocationEmitter( MethodInfo methodInfo, Flags bindingFlags ) 28 | : this( methodInfo.DeclaringType, bindingFlags, methodInfo.Name, methodInfo.GetParameters().ToTypeArray(), methodInfo ) 29 | { 30 | } 31 | 32 | public MethodInvocationEmitter( Type targetType, Flags bindingFlags, string name, Type[] parameterTypes ) 33 | : this( targetType, bindingFlags, name, parameterTypes, null ) 34 | { 35 | } 36 | 37 | private MethodInvocationEmitter( Type targetType, Flags bindingFlags, string name, Type[] parameterTypes, 38 | MemberInfo methodInfo ) 39 | : base(new CallInfo(targetType, null, bindingFlags, MemberTypes.Method, name, parameterTypes, methodInfo, true)) 40 | { 41 | } 42 | 43 | public MethodInvocationEmitter( CallInfo callInfo ) : base( callInfo ) 44 | { 45 | } 46 | 47 | protected internal override DynamicMethod CreateDynamicMethod() 48 | { 49 | return CreateDynamicMethod( "invoke", CallInfo.TargetType, Constants.ObjectType, 50 | new[] { Constants.ObjectType, Constants.ObjectType.MakeArrayType() } ); 51 | } 52 | 53 | protected internal override Delegate CreateDelegate() 54 | { 55 | var method = (MethodInfo) CallInfo.MemberInfo ?? LookupUtils.GetMethod( CallInfo ); 56 | CallInfo.IsStatic = method.IsStatic; 57 | const byte paramArrayIndex = 1; 58 | bool hasReturnType = method.ReturnType != Constants.VoidType; 59 | 60 | byte startUsableLocalIndex = 0; 61 | if( CallInfo.HasRefParam ) 62 | { 63 | startUsableLocalIndex = CreateLocalsForByRefParams( paramArrayIndex, method ); 64 | // create by_ref_locals from argument array 65 | Generator.DeclareLocal( hasReturnType 66 | ? method.ReturnType 67 | : Constants.ObjectType ); // T result; 68 | GenerateInvocation( method, paramArrayIndex, (byte) (startUsableLocalIndex + 1) ); 69 | if( hasReturnType ) 70 | { 71 | Generator.stloc( startUsableLocalIndex ); // result = ; 72 | } 73 | AssignByRefParamsToArray( paramArrayIndex ); // store by_ref_locals back to argument array 74 | } 75 | else 76 | { 77 | Generator.DeclareLocal( hasReturnType 78 | ? method.ReturnType 79 | : Constants.ObjectType ); // T result; 80 | GenerateInvocation( method, paramArrayIndex, (byte) (startUsableLocalIndex + 1) ); 81 | if( hasReturnType ) 82 | { 83 | Generator.stloc( startUsableLocalIndex ); // result = ; 84 | } 85 | } 86 | 87 | if( CallInfo.ShouldHandleInnerStruct ) 88 | { 89 | StoreLocalToInnerStruct( (byte) (startUsableLocalIndex + 1) ); // ((ValueTypeHolder)this)).Value = tmpStr; 90 | } 91 | if( hasReturnType ) 92 | { 93 | Generator.ldloc( startUsableLocalIndex ) // push result; 94 | .boxIfValueType( method.ReturnType ); // box result; 95 | } 96 | else 97 | { 98 | Generator.ldnull.end(); // load null 99 | } 100 | Generator.ret(); 101 | 102 | return Method.CreateDelegate( typeof(MethodInvoker) ); 103 | } 104 | 105 | private void GenerateInvocation( MethodInfo methodInfo, byte paramArrayIndex, byte structLocalPosition ) 106 | { 107 | if( ! CallInfo.IsStatic ) 108 | { 109 | Generator.ldarg_0.end(); // load arg-0 (this/null); 110 | if( CallInfo.ShouldHandleInnerStruct ) 111 | { 112 | Generator.DeclareLocal( CallInfo.TargetType ); // TargetType tmpStr; 113 | LoadInnerStructToLocal( structLocalPosition ); // tmpStr = ((ValueTypeHolder)this)).Value; 114 | } 115 | else 116 | { 117 | Generator.castclass( CallInfo.TargetType ); // (TargetType)arg-0; 118 | } 119 | } 120 | PushParamsOrLocalsToStack( paramArrayIndex ); // push arguments and by_ref_locals 121 | Generator.call( methodInfo.IsStatic || CallInfo.IsTargetTypeStruct, methodInfo ); // call OR callvirt 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Emitter/MapEmitter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using System.Reflection; 23 | using System.Reflection.Emit; 24 | 25 | namespace Fasterflect.Emitter 26 | { 27 | internal class MapEmitter : BaseEmitter 28 | { 29 | private readonly Type sourceType; 30 | private readonly MemberTypes sourceMemberTypes; 31 | private readonly MemberTypes targetMemberTypes; 32 | private readonly string[] names; 33 | 34 | public MapEmitter(Type sourceType, Type targetType, MemberTypes sourceMemberTypes, MemberTypes targetMemberTypes, 35 | Flags bindingFlags, params string[] names) 36 | : base(new MapCallInfo(targetType, null, 37 | // Auto-apply IgnoreCase if we're mapping from one membertype to another 38 | Flags.SetIf(bindingFlags, Flags.IgnoreCase, (sourceMemberTypes & targetMemberTypes) != sourceMemberTypes), 39 | MemberTypes.Custom, 40 | "Fasterflect_Map", 41 | Type.EmptyTypes, 42 | null, 43 | false, 44 | sourceType, 45 | sourceMemberTypes, 46 | targetMemberTypes, 47 | names)) 48 | { 49 | this.sourceType = sourceType; 50 | this.sourceMemberTypes = sourceMemberTypes; 51 | this.targetMemberTypes = targetMemberTypes; 52 | this.names = names; 53 | } 54 | 55 | protected internal override DynamicMethod CreateDynamicMethod() 56 | { 57 | return CreateDynamicMethod(sourceType.Name, sourceType, null, new[] { Constants.ObjectType, Constants.ObjectType }); 58 | } 59 | 60 | protected internal override Delegate CreateDelegate() 61 | { 62 | bool handleInnerStruct = CallInfo.ShouldHandleInnerStruct; 63 | if (handleInnerStruct) 64 | { 65 | Generator.ldarg_1.end(); // load arg-1 (target) 66 | Generator.DeclareLocal(CallInfo.TargetType); // TargetType localStr; 67 | Generator 68 | .castclass(Constants.StructType) // (ValueTypeHolder)wrappedStruct 69 | .callvirt(StructGetMethod) // .get_Value() 70 | .unbox_any(CallInfo.TargetType) // unbox 71 | .stloc(0); // localStr = 72 | } 73 | 74 | foreach (var pair in GetMatchingMembers()) 75 | { 76 | if (handleInnerStruct) 77 | Generator.ldloca_s(0).end(); // load &localStr 78 | else 79 | Generator.ldarg_1.castclass(CallInfo.TargetType).end(); // ((TargetType)target) 80 | Generator.ldarg_0.castclass(sourceType); 81 | GenerateGetMemberValue(pair.Key); 82 | GenerateSetMemberValue(pair.Value); 83 | } 84 | 85 | if (handleInnerStruct) 86 | { 87 | StoreLocalToInnerStruct(1, 0); // ((ValueTypeHolder)this)).Value = tmpStr 88 | } 89 | 90 | Generator.ret(); 91 | return Method.CreateDelegate(typeof(ObjectMapper)); 92 | } 93 | 94 | private void GenerateGetMemberValue(MemberInfo member) 95 | { 96 | if (member is FieldInfo) 97 | { 98 | Generator.ldfld((FieldInfo)member); 99 | } 100 | else 101 | { 102 | var method = ((PropertyInfo)member).GetGetMethod(true); 103 | Generator.callvirt(method, null); 104 | } 105 | } 106 | 107 | private void GenerateSetMemberValue(MemberInfo member) 108 | { 109 | if (member is FieldInfo) 110 | { 111 | Generator.stfld((FieldInfo)member); 112 | } 113 | else 114 | { 115 | var method = ((PropertyInfo)member).GetSetMethod(true); 116 | Generator.callvirt(method, null); 117 | } 118 | } 119 | 120 | private IEnumerable> GetMatchingMembers() 121 | { 122 | StringComparison comparison = CallInfo.BindingFlags.IsSet(Flags.IgnoreCase) 123 | ? StringComparison.OrdinalIgnoreCase 124 | : StringComparison.Ordinal; 125 | var query = from s in sourceType.Members(sourceMemberTypes, CallInfo.BindingFlags, names) 126 | from t in CallInfo.TargetType.Members(targetMemberTypes, CallInfo.BindingFlags, names) 127 | where s.Name.Equals(t.Name, comparison) && 128 | t.Type().GetTypeInfo().IsAssignableFrom(s.Type()) && 129 | s.IsReadable() && t.IsWritable() 130 | select new { Source = s, Target = t }; 131 | return query.ToDictionary(k => k.Source, v => v.Target); 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/AssemblyExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using System.Reflection; 23 | 24 | namespace Fasterflect 25 | { 26 | /// 27 | /// Extension methods for inspecting assemblies. 28 | /// 29 | public static class AssemblyExtensions 30 | { 31 | #region Types 32 | /// 33 | /// Gets all types in the given matching the optional list 34 | /// . 35 | /// 36 | /// The assembly in which to look for types. 37 | /// An optional list of names against which to filter the result. If this is 38 | /// null or left empty, all types are returned. 39 | /// A list of all matching types. This method never returns null. 40 | public static IList Types( this Assembly assembly, params string[] names ) 41 | { 42 | return assembly.Types( Flags.None, names ); 43 | } 44 | 45 | /// 46 | /// Gets all types in the given matching the specified 47 | /// and the optional list . 48 | /// 49 | /// The assembly in which to look for types. 50 | /// The used to customize how results 51 | /// are filters. If the option is specified any name 52 | /// comparisons will use instead of . 53 | /// An optional list of names against which to filter the result. If this is 54 | /// null or left empty, all types are returned. 55 | /// A list of all matching types. This method never returns null. 56 | public static IList Types( this Assembly assembly, Flags bindingFlags, params string[] names ) 57 | { 58 | Type[] types = assembly.GetTypes(); 59 | 60 | bool hasNames = names != null && names.Length > 0; 61 | bool partialNameMatch = bindingFlags.IsSet( Flags.PartialNameMatch ); 62 | 63 | return hasNames 64 | ? types.Where( t => names.Any( n => partialNameMatch ? t.Name.Contains( n ) : t.Name == n ) ).ToArray() 65 | : types; 66 | } 67 | #endregion 68 | 69 | #region TypesImplementing 70 | /// 71 | /// Gets all types in the given that implement the given . 72 | /// 73 | /// The interface types should implement. 74 | /// The assembly in which to look for types. 75 | /// A list of all matching types. This method never returns null. 76 | public static IList TypesImplementing( this Assembly assembly ) 77 | { 78 | Type[] types = assembly.GetTypes(); 79 | return types.Where( t => t.Implements() ).ToList(); 80 | } 81 | #endregion 82 | 83 | #region TypesWith Lookup 84 | /// 85 | /// Gets all types in the given that are decorated with an 86 | /// of the given . 87 | /// 88 | /// A list of all matching types. This value will never be null. 89 | public static IList TypesWith( this Assembly assembly, Type attributeType ) 90 | { 91 | IEnumerable query = from t in assembly.GetTypes() 92 | where t.GetTypeInfo().HasAttribute( attributeType ) 93 | select t; 94 | return query.ToArray(); 95 | } 96 | 97 | /// 98 | /// Gets all types in the given that are decorated with an 99 | /// of the given type . 100 | /// 101 | /// A list of all matching types. This value will never be null. 102 | public static IList TypesWith( this Assembly assembly ) where T : Attribute 103 | { 104 | return assembly.TypesWith( typeof(T) ); 105 | } 106 | #endregion 107 | } 108 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Lookup/ConstructorTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using System.Linq; 24 | using System.Reflection; 25 | using Fasterflect; 26 | using NUnit.Framework; 27 | 28 | namespace FasterflectTest.Lookup 29 | { 30 | [TestFixture] 31 | public class ConstructorTest 32 | { 33 | #region Sample Classes 34 | private class PersonClass 35 | { 36 | public int Age; 37 | public int? Id; 38 | public string Name; 39 | public object Data; 40 | public PersonClass Peer; 41 | public PersonClass[] Peers; 42 | 43 | private PersonClass() { } 44 | internal PersonClass(out int i, out string s) 45 | { 46 | i = 1; 47 | s = "changed"; 48 | } 49 | internal PersonClass(int age) { Age = age; } 50 | internal PersonClass(int? id) { Id = id; } 51 | protected PersonClass(string name) { Name = name; } 52 | protected PersonClass(object data) { Data = data; } 53 | public PersonClass(PersonClass peer) { Peer = peer; } 54 | public PersonClass(PersonClass[] peers) { Peers = peers; } 55 | internal PersonClass(int age, int? id, string name, PersonClass peer, PersonClass[] peers) 56 | { 57 | Age = age; 58 | Id = id; 59 | Name = name; 60 | Peer = peer; 61 | Peers = peers; 62 | } 63 | } 64 | 65 | private class PersonStruct 66 | { 67 | public int Age; 68 | public int? Id; 69 | public string Name; 70 | public object Data; 71 | public PersonClass Peer; 72 | public PersonClass[] Peers; 73 | 74 | private PersonStruct() { } 75 | internal PersonStruct(out int i, out string s) 76 | { 77 | i = 1; 78 | s = "changed"; 79 | } 80 | internal PersonStruct(int age) { Age = age; } 81 | internal PersonStruct(int? id) { Id = id; } 82 | protected PersonStruct(string name) { Name = name; } 83 | protected PersonStruct(object data) { Data = data; } 84 | public PersonStruct(PersonClass peer) { Peer = peer; } 85 | public PersonStruct(PersonClass[] peers) { Peers = peers; } 86 | internal PersonStruct(int age, int? id, string name, PersonClass peer, PersonClass[] peers) 87 | { 88 | Age = age; 89 | Id = id; 90 | Name = name; 91 | Peer = peer; 92 | Peers = peers; 93 | } 94 | } 95 | 96 | class Employee : PersonClass 97 | { 98 | internal Employee(int age) : base(age) { } 99 | } 100 | 101 | private static readonly List TypeList = new List 102 | { 103 | typeof(PersonClass), 104 | typeof(PersonStruct) 105 | }; 106 | #endregion 107 | 108 | #region Constructor Lookup Tests 109 | [Test] 110 | public void TestFindAllConstructorsOnPersonClassShouldFindNine() 111 | { 112 | IList constructors = typeof(PersonClass).Constructors().ToList(); 113 | Assert.IsNotNull( constructors ); 114 | Assert.AreEqual( 9, constructors.Count ); 115 | } 116 | 117 | [Test] 118 | public void TestFindSpecificConstructorOnPersonClassShouldReturnNullForNoMatch() 119 | { 120 | Type[] paramTypes = new[] { typeof(int), typeof(int) }; 121 | Assert.IsNull( typeof(PersonClass).Constructor( paramTypes ) ); 122 | } 123 | 124 | [Test] 125 | public void TestFindSpecificConstructorOnPersonClassShouldReturnSingleForMatch() 126 | { 127 | Type[] paramTypes = new[] { typeof(int) }; 128 | ConstructorInfo constructor = typeof(PersonClass).Constructor( paramTypes ); 129 | Assert.IsNotNull( constructor ); 130 | Assert.AreEqual( "age", constructor.GetParameters()[ 0 ].Name ); 131 | 132 | paramTypes = new[] { typeof(int?) }; 133 | constructor = typeof(PersonClass).Constructor( paramTypes ); 134 | Assert.IsNotNull( constructor ); 135 | Assert.AreEqual( "id", constructor.GetParameters()[ 0 ].Name ); 136 | } 137 | 138 | [Test] 139 | public void TestFindSpecificConstructorsOnPersonClass() 140 | { 141 | IList constructors = typeof(PersonClass).Constructors().ToList(); 142 | Assert.IsNotNull( constructors ); 143 | Assert.AreEqual( 9, constructors.Count ); 144 | } 145 | 146 | [Test] 147 | public void TestConstructorLookupOnEmployeeShouldFindOne() 148 | { 149 | IList constructors = typeof(Employee).Constructors().ToList(); 150 | Assert.IsNotNull( constructors ); 151 | Assert.AreEqual( 1, constructors.Count ); 152 | } 153 | #endregion 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Services/EventHandlerTest.cs: -------------------------------------------------------------------------------- 1 | using Fasterflect; 2 | using NUnit.Framework; 3 | 4 | namespace FasterflectTest.Services 5 | { 6 | [TestFixture] 7 | public class EventHandlerTest 8 | { 9 | class EventSource 10 | { 11 | private delegate void VoidOp(); 12 | private delegate string StringOp(string s); 13 | public delegate int IntOp(int i); 14 | 15 | #pragma warning disable 0169 16 | // ReSharper disable UnusedMember.Local 17 | private VoidOp voidOp; 18 | private StringOp stringOp; 19 | private IntOp intOp; 20 | 21 | private static VoidOp StaticVoidOp; 22 | private static StringOp StaticStringOp; 23 | private static IntOp StaticIntOp; 24 | 25 | private event IntOp intEvent; 26 | private static event IntOp StaticIntEvent; 27 | // ReSharper restore UnusedMember.Local 28 | #pragma warning restore 0169 29 | 30 | public int TriggerEvents(int i) 31 | { 32 | return intEvent(i); 33 | } 34 | 35 | public static int TriggerStaticEvents(int i) 36 | { 37 | return StaticIntEvent(i); 38 | } 39 | } 40 | 41 | [Test] 42 | public void Test_assign_static_no_arg_void_return_delegate() 43 | { 44 | var type = typeof(EventSource); 45 | var call = false; 46 | type.AssignHandler("StaticVoidOp", args => call = true); 47 | type.InvokeDelegate("StaticVoidOp"); 48 | Assert.AreEqual( true, call ); 49 | } 50 | 51 | [Test] 52 | public void Test_handle_static_int_arg_int_return_delegate() 53 | { 54 | var type = typeof(EventSource); 55 | var sum = 0; 56 | type.AddHandler("StaticIntOp", args => sum += (int)args[0] * 2); 57 | type.AddHandler("StaticIntOp", args => sum += (int)args[0] * 3); 58 | var result = (int)type.InvokeDelegate("StaticIntOp", 2); 59 | Assert.AreEqual(10, sum); 60 | Assert.AreEqual(10, result); 61 | } 62 | 63 | [Test] 64 | public void Test_assign_static_string_arg_string_return_delegate() 65 | { 66 | var type = typeof(EventSource); 67 | type.AddHandler("StaticStringOp", args => (string)args[0] + "1"); 68 | type.AddHandler("StaticStringOp", args => (string)args[0] + "2"); 69 | var result = (string)type.InvokeDelegate("StaticStringOp", "A"); 70 | Assert.AreEqual("A2", result); 71 | } 72 | 73 | [Test] 74 | public void Test_assign_instance_no_arg_void_return_delegate() 75 | { 76 | var target = typeof(EventSource).CreateInstance( ); 77 | var call = false; 78 | target.AssignHandler("voidOp", args => call = true); 79 | target.InvokeDelegate("voidOp"); 80 | Assert.AreEqual(true, call); 81 | } 82 | 83 | [Test] 84 | public void Test_handle_instance_int_arg_int_return_delegate() 85 | { 86 | var target = typeof(EventSource).CreateInstance(); 87 | var sum = 0; 88 | target.AddHandler("intOp", args => sum += (int)args[0] * 2); 89 | target.AddHandler("intOp", args => sum += (int)args[0] * 3); 90 | var result = (int)target.InvokeDelegate("intOp", 2); 91 | Assert.AreEqual(10, sum); 92 | Assert.AreEqual(10, result); 93 | } 94 | 95 | [Test] 96 | public void Test_assign_instance_string_arg_string_return_delegate() 97 | { 98 | var target = typeof(EventSource).CreateInstance( ); 99 | target.AddHandler("stringOp", args => (string)args[0] + "1"); 100 | target.AddHandler("stringOp", args => (string)args[0] + "2"); 101 | var result = (string)target.InvokeDelegate("stringOp", "A"); 102 | Assert.AreEqual("A2", result); 103 | } 104 | 105 | [Test] 106 | public void Test_handle_instance_int_arg_int_return_event() 107 | { 108 | var target = typeof(EventSource).CreateInstance(); 109 | var sum = 0; 110 | target.AddHandler("intEvent", args => sum += (int)args[0] * 2); 111 | target.AddHandler("intEvent", args => sum += (int)args[0] * 3); 112 | var result = target.CallMethod("TriggerEvents", 2); 113 | Assert.AreEqual(10, sum); 114 | Assert.AreEqual(10, result); 115 | } 116 | 117 | [Test] 118 | public void Test_handle_static_int_arg_int_return_event() 119 | { 120 | var type = typeof(EventSource); 121 | var sum = 0; 122 | type.AddHandler("StaticIntEvent", args => sum += (int)args[0] * 2); 123 | type.AddHandler("StaticIntEvent", args => sum += (int)args[0] * 3); 124 | var result = type.CallMethod("TriggerStaticEvents", 2); 125 | Assert.AreEqual(10, sum); 126 | Assert.AreEqual(10, result); 127 | } 128 | 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Services/TryCallMethodExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using System.Reflection; 23 | using Fasterflect.Probing; 24 | 25 | namespace Fasterflect 26 | { 27 | /// 28 | /// Extension methods for creating object instances when you do not know which constructor to call. 29 | /// 30 | public static class TryCallMethodExtensions 31 | { 32 | #region Method Invocation (TryCallMethod) 33 | /// 34 | /// Obtains a list of all methods with the given on the given 35 | /// , and invokes the best match for the parameters obtained from the 36 | /// public properties of the supplied object. 37 | /// TryCallMethod is very liberal and attempts to convert values that are not otherwise 38 | /// considered compatible, such as between strings and enums or numbers, Guids and byte[16], etc. 39 | /// 40 | /// The result of the invocation. 41 | public static object TryCallMethod( this object obj, string methodName, bool mustUseAllParameters, object sample ) 42 | { 43 | Type sourceType = sample.GetType(); 44 | var sourceInfo = SourceInfo.CreateFromType( sourceType ); 45 | var paramValues = sourceInfo.GetParameterValues( sample ); 46 | return obj.TryCallMethod( methodName, mustUseAllParameters, sourceInfo.ParamNames, sourceInfo.ParamTypes, paramValues ); 47 | } 48 | 49 | /// 50 | /// Obtains a list of all methods with the given on the given 51 | /// , and invokes the best match for the parameters obtained from the 52 | /// values in the supplied dictionary. 53 | /// TryCallMethod is very liberal and attempts to convert values that are not otherwise 54 | /// considered compatible, such as between strings and enums or numbers, Guids and byte[16], etc. 55 | /// 56 | /// The result of the invocation. 57 | public static object TryCallMethod( this object obj, string methodName, bool mustUseAllParameters, IDictionary parameters ) 58 | { 59 | bool hasParameters = parameters != null && parameters.Count > 0; 60 | string[] names = hasParameters ? parameters.Keys.ToArray() : new string[ 0 ]; 61 | object[] values = hasParameters ? parameters.Values.ToArray() : new object[ 0 ]; 62 | return obj.TryCallMethod( methodName, mustUseAllParameters, names, values.ToTypeArray(), values ); 63 | } 64 | 65 | /// 66 | /// Obtains a list of all methods with the given on the given 67 | /// , and invokes the best match for the supplied parameters. 68 | /// TryCallMethod is very liberal and attempts to convert values that are not otherwise 69 | /// considered compatible, such as between strings and enums or numbers, Guids and byte[16], etc. 70 | /// 71 | /// The type of which an instance should be created. 72 | /// The name of the overloaded methods. 73 | /// Specifies whether all supplied parameters must be used in the 74 | /// invocation. Unless you know what you are doing you should pass true for this parameter. 75 | /// The names of the supplied parameters. 76 | /// The types of the supplied parameters. 77 | /// The values of the supplied parameters. 78 | /// The result of the invocation. 79 | public static object TryCallMethod( this object obj, string methodName, bool mustUseAllParameters, 80 | string[] parameterNames, Type[] parameterTypes, object[] parameterValues ) 81 | { 82 | bool isStatic = obj is Type; 83 | var type = isStatic ? obj as Type : obj.GetType(); 84 | var names = parameterNames ?? new string[ 0 ]; 85 | var types = parameterTypes ?? new Type[ 0 ]; 86 | var values = parameterValues ?? new object[ 0 ]; 87 | if( names.Length != values.Length || names.Length != types.Length ) 88 | { 89 | throw new ArgumentException( "Mismatching name, type and value arrays (must be of identical length)." ); 90 | } 91 | MethodMap map = MapFactory.DetermineBestMethodMatch( type.Methods( methodName ).Cast(), mustUseAllParameters, names, types, values ); 92 | return isStatic ? map.Invoke( values ) : map.Invoke( obj, values ); 93 | } 94 | #endregion 95 | } 96 | } -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Services/XmlTransformerExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Reflection; 21 | using System.Text; 22 | 23 | namespace Fasterflect 24 | { 25 | /// 26 | /// This class defines extensions for transforming any object to XML. 27 | /// 28 | public static class XmlTransformerExtensions 29 | { 30 | #region ToXml 31 | /// 32 | /// Generates a string representation of the given using the default 33 | /// . The output will contain one element for every readable 34 | /// property on and process reference properties (other than strings) 35 | /// recursively. This method does not handle cyclic references - passing in such an object 36 | /// graph will cause an infinite loop. 37 | /// 38 | /// The object to convert to XML. 39 | /// A string containing the generated XML data. 40 | public static string ToXml( this object obj ) 41 | { 42 | return ToXml( obj, FormatOptions.Default ); 43 | } 44 | 45 | /// 46 | /// Generates a string representation of the given using the default 47 | /// . The output will contain one element for every readable 48 | /// property on and process reference properties (other than strings) 49 | /// recursively. This method does not handle cyclic references - passing in such an object 50 | /// graph will cause an infinite loop. 51 | /// 52 | /// The object to convert to XML. 53 | /// 54 | /// A string containing the generated XML data. 55 | public static string ToXml( this object obj, FormatOptions options ) 56 | { 57 | bool newLineAfterElement = (options & FormatOptions.NewLineAfterElement) == FormatOptions.NewLineAfterElement; 58 | string afterElement = newLineAfterElement ? Environment.NewLine : String.Empty; 59 | bool tabIndent = (options & FormatOptions.UseSpaces) != FormatOptions.UseSpaces; 60 | string indent = tabIndent ? "\t" : " "; 61 | bool addHeader = (options & FormatOptions.AddHeader) == FormatOptions.AddHeader; 62 | string header = addHeader ? "" + Environment.NewLine : string.Empty; 63 | return ToXml( obj, header, afterElement, indent, String.Empty ); 64 | } 65 | #endregion 66 | 67 | #region ToXml Implementation 68 | private static string ToXml( object obj, string header, string afterElementDecoration, 69 | string indentDecoration, string currentIndent ) 70 | { 71 | StringBuilder sb = new StringBuilder(); 72 | Type type = obj.GetType(); 73 | sb.Append( header ); 74 | sb.AppendFormat( "{0}<{1}>{2}", currentIndent, type.Name, afterElementDecoration ); 75 | 76 | currentIndent = Indent( indentDecoration, currentIndent ); 77 | // enumerate all instance properties 78 | foreach( var propertyInfo in type.Properties() ) 79 | { 80 | // ignore properties we cannot read 81 | if( propertyInfo.CanRead && propertyInfo.Name != "Item" ) 82 | { 83 | object propertyValue = propertyInfo.Get( obj ); 84 | Type propertyType = propertyInfo.PropertyType; 85 | if( (propertyType.GetTypeInfo().IsClass || propertyType.GetTypeInfo().IsInterface) && propertyType != typeof(string) ) 86 | { 87 | } 88 | if( (propertyType.GetTypeInfo().IsClass || propertyType.GetTypeInfo().IsInterface) && propertyType != typeof(string) ) 89 | { 90 | sb.AppendFormat( ToXml( propertyValue, string.Empty, afterElementDecoration, indentDecoration, currentIndent ) ); 91 | } 92 | else 93 | { 94 | sb.AppendFormat( "{0}<{1}>{2}{3}", 95 | currentIndent, 96 | propertyInfo.Name, 97 | propertyValue, 98 | afterElementDecoration ); 99 | } 100 | } 101 | } 102 | currentIndent = Unindent( indentDecoration, currentIndent ); 103 | sb.AppendFormat( "{0}{2}", currentIndent, type.Name, afterElementDecoration ); 104 | return sb.ToString(); 105 | } 106 | 107 | private static string Indent( string indent, string currentIndent ) 108 | { 109 | return currentIndent + indent; 110 | } 111 | 112 | private static string Unindent( string indent, string currentIndent ) 113 | { 114 | return currentIndent.Substring( 0, currentIndent.Length - indent.Length ); 115 | } 116 | #endregion 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Fasterflect.Netstandard/Extensions/Core/MethodInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // Copyright 2010 Buu Nguyen, Morten Mertner 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 17 | #endregion 18 | 19 | using System; 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using System.Reflection; 23 | using Fasterflect.Emitter; 24 | 25 | namespace Fasterflect 26 | { 27 | /// 28 | /// Extension methods for inspecting, invoking and working with methods. 29 | /// 30 | public static class MethodInfoExtensions 31 | { 32 | #region Access 33 | /// 34 | /// Invokes the static method identified by with 35 | /// as arguments. Leave empty if the method has no argument. 36 | /// 37 | /// The return value of the method. 38 | /// If the method has no return type, null is returned. 39 | public static object Call( this MethodInfo methodInfo, params object[] parameters ) 40 | { 41 | return methodInfo.DelegateForCallMethod()( null, parameters ); 42 | } 43 | 44 | /// 45 | /// Invokes the instance method identified by on the object 46 | /// with as arguments. 47 | /// Leave empty if the method has no argument. 48 | /// 49 | /// The return value of the method. 50 | /// If the method has no return type, null is returned. 51 | public static object Call( this MethodInfo methodInfo, object obj, params object[] parameters ) 52 | { 53 | return methodInfo.DelegateForCallMethod()( obj, parameters ); 54 | } 55 | 56 | /// 57 | /// Creates a delegate which can invoke the instance method identified by . 58 | /// 59 | public static MethodInvoker DelegateForCallMethod( this MethodInfo methodInfo ) 60 | { 61 | var flags = methodInfo.IsStatic ? Flags.StaticAnyVisibility : Flags.InstanceAnyVisibility; 62 | return (MethodInvoker) new MethodInvocationEmitter( methodInfo, flags ).GetDelegate(); 63 | } 64 | #endregion 65 | 66 | #region Method Parameter Lookup 67 | /// 68 | /// Gets all parameters for the given . 69 | /// 70 | /// The list of parameters for the method. This value will never be null. 71 | public static IList Parameters( this MethodBase method ) 72 | { 73 | return method.GetParameters(); 74 | } 75 | #endregion 76 | 77 | #region Method Signature Comparer 78 | /// 79 | /// Compares the signature of the method with the given parameter types and returns true if 80 | /// all method parameters have the same order and type. Parameter names are not considered. 81 | /// 82 | /// True if the supplied parameter type array matches the method parameters array, false otherwise. 83 | public static bool HasParameterSignature( this MethodBase method, Type[] parameters ) 84 | { 85 | bool quickCheckResult = method.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameters); 86 | 87 | if (quickCheckResult) 88 | return true; 89 | 90 | //TODO: Figure out why we had to add this. 91 | ParameterInfo[] parameterInfos = method.GetParameters(); 92 | 93 | bool sameSize = parameterInfos.Length == parameters.Length; 94 | 95 | if (!sameSize) 96 | return false; 97 | 98 | bool longResult = true; 99 | 100 | //TODO: For some reason netstandard port didn't support polymorphic ctor inspection. 101 | //use both length or you will throw 102 | for (int i = 0; i < parameterInfos.Length; i++) 103 | { 104 | if (!parameterInfos[i].ParameterType.GetTypeInfo().IsAssignableFrom(parameters[i])) 105 | longResult = false; 106 | } 107 | 108 | return longResult; 109 | } 110 | 111 | /// 112 | /// Compares the signature of the method with the given parameter types and returns true if 113 | /// all method parameters have the same order and type. Parameter names are not considered. 114 | /// 115 | /// True if the supplied parameter type array matches the method parameters array, false otherwise. 116 | public static bool HasParameterSignature( this MethodBase method, ParameterInfo[] parameters ) 117 | { 118 | //Pass to polymorphic implemented paramater sig test 119 | return HasParameterSignature(method, parameters.Select(p => p.ParameterType).ToArray()); 120 | } 121 | #endregion 122 | } 123 | } -------------------------------------------------------------------------------- /tests/Fasterflect.Netframework.Tests/Invocation/DelegateTest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | 3 | // Copyright 2010 Buu Nguyen, Morten Mertner 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // The latest version of this file can be found at http://fasterflect.codeplex.com/ 18 | 19 | #endregion 20 | 21 | using System; 22 | using Fasterflect; 23 | using FasterflectTest.SampleModel.People; 24 | using NUnit.Framework; 25 | 26 | namespace FasterflectTest.Invocation 27 | { 28 | [TestFixture] 29 | public class DelegateTest : BaseInvocationTest 30 | { 31 | [Test] 32 | public void TestDelegateRetrievalMethodsReturnCorrectDelegateType() 33 | { 34 | RunWith( ( Type type ) => 35 | { 36 | var funcs = new Func[] 37 | { 38 | () => type.MakeArrayType().DelegateForGetElement(), 39 | () => type.MakeArrayType().DelegateForSetElement(), 40 | () => type.DelegateForCreateInstance(), 41 | () => type.DelegateForCreateInstance( new[] { typeof(string), typeof(int) } ), 42 | () => 43 | type.DelegateForCallMethod( "AdjustTotalPeopleCreated", new[] { typeof(int) } ), 44 | () => type.DelegateForCallMethod( "GetTotalPeopleCreated" ), 45 | () => type.DelegateForSetFieldValue( "totalPeopleCreated" ), 46 | () => type.DelegateForGetFieldValue( "totalPeopleCreated" ), 47 | () => type.DelegateForSetPropertyValue( "TotalPeopleCreated" ), 48 | () => type.DelegateForGetPropertyValue( "TotalPeopleCreated" ), 49 | () => type.DelegateForGetIndexer( new[] { typeof(string) } ), 50 | () => 51 | type.DelegateForSetIndexer( new[] 52 | { 53 | typeof(string), 54 | type == typeof(Person) ? type : typeof(PersonStruct?) 55 | } ) 56 | , 57 | () => type.DelegateForGetIndexer( new[] { typeof(string), typeof(int) } ), 58 | () => type.DelegateForSetFieldValue( "name" ), 59 | () => type.DelegateForGetFieldValue( "name" ), 60 | () => type.DelegateForSetPropertyValue( "Age" ), 61 | () => type.DelegateForGetPropertyValue( "Age" ), 62 | () => type.DelegateForCallMethod( "Walk", new[] { typeof(double) } ), 63 | () => 64 | type.DelegateForCallMethod( "Walk", 65 | new[] { typeof(double), typeof(double).MakeByRefType() } ), 66 | }; 67 | var types = new[] 68 | { 69 | typeof(ArrayElementGetter), 70 | typeof(ArrayElementSetter), 71 | typeof(ConstructorInvoker), 72 | typeof(ConstructorInvoker), 73 | typeof(MethodInvoker), 74 | typeof(MethodInvoker), 75 | typeof(MemberSetter), 76 | typeof(MemberGetter), 77 | typeof(MemberSetter), 78 | typeof(MemberGetter), 79 | typeof(MethodInvoker), 80 | typeof(MethodInvoker), 81 | typeof(MethodInvoker), 82 | typeof(MemberSetter), 83 | typeof(MemberGetter), 84 | typeof(MemberSetter), 85 | typeof(MemberGetter), 86 | typeof(MethodInvoker), 87 | typeof(MethodInvoker) 88 | }; 89 | 90 | for( int i = 0; i < funcs.Length; i++ ) 91 | { 92 | var result = funcs[ i ](); 93 | Assert.IsNotNull( result ); 94 | Assert.IsInstanceOfType(types[ i ], result); 95 | } 96 | } ); 97 | } 98 | } 99 | } --------------------------------------------------------------------------------