2020-12-20 08:36:11 +01:00
|
|
|
// Copyright (c) Umbraco.
|
|
|
|
|
// See LICENSE for more details.
|
|
|
|
|
|
|
|
|
|
using System;
|
2018-10-25 15:29:29 +02:00
|
|
|
using System.Collections.Generic;
|
2020-05-03 15:51:46 +01:00
|
|
|
using System.Linq;
|
2017-09-29 15:50:30 +02:00
|
|
|
using System.Reflection;
|
2020-05-03 15:51:46 +01:00
|
|
|
using Newtonsoft.Json;
|
2017-09-27 21:16:09 +02:00
|
|
|
using NUnit.Framework;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core;
|
2017-09-27 21:16:09 +02:00
|
|
|
using Umbraco.Core;
|
|
|
|
|
|
2021-02-10 14:58:22 +01:00
|
|
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
|
|
|
|
[TestFixture]
|
|
|
|
|
public class ReflectionUtilitiesTests
|
|
|
|
|
{
|
|
|
|
|
[Test]
|
2017-09-29 15:50:30 +02:00
|
|
|
public void EmitCtorEmits()
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1> ctor1 = ReflectionUtilities.EmitConstructor<Func<Class1>>();
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class1>(ctor1());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<object> ctor2 = ReflectionUtilities.EmitConstructor<Func<object>>(declaring: typeof(Class1));
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class1>(ctor2());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<int, Class3> ctor3 = ReflectionUtilities.EmitConstructor<Func<int, Class3>>();
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class3>(ctor3(42));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<int, object> ctor4 = ReflectionUtilities.EmitConstructor<Func<int, object>>(declaring: typeof(Class3));
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class3>(ctor4(42));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorEmitsFromInfo()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
ConstructorInfo ctorInfo = typeof(Class1).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, Array.Empty<Type>(), null);
|
|
|
|
|
Func<Class1> ctor1 = ReflectionUtilities.EmitConstructor<Func<Class1>>(ctorInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class1>(ctor1());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
ctorInfo = typeof(Class1).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, new[] { typeof(int) }, null);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<int, object> ctor3 = ReflectionUtilities.EmitConstructor<Func<int, object>>(ctorInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class1>(ctor3(42));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2018-10-16 10:58:17 +02:00
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitConstructor<Func<string, object>>(ctorInfo));
|
2017-09-29 15:50:30 +02:00
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorEmitsPrivateCtor()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<string, Class3> ctor = ReflectionUtilities.EmitConstructor<Func<string, Class3>>();
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsInstanceOf<Class3>(ctor("foo"));
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2020-12-20 08:36:11 +01:00
|
|
|
public void EmitCtorThrowsIfNotFound() =>
|
2018-11-18 11:05:14 +01:00
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitConstructor<Func<bool, Class3>>());
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitCtorThrowsIfInvalid()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
ConstructorInfo ctorInfo = typeof(Class1).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, Array.Empty<Type>(), null);
|
2018-10-16 10:58:17 +02:00
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitConstructor<Func<Class2>>(ctorInfo));
|
2017-09-29 15:50:30 +02:00
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
2020-12-20 08:36:11 +01:00
|
|
|
public void EmitCtorReturnsNull() =>
|
2018-11-18 11:05:14 +01:00
|
|
|
Assert.IsNull(ReflectionUtilities.EmitConstructor<Func<bool, Class3>>(false));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
|
|
|
|
[Test]
|
2017-09-29 15:50:30 +02:00
|
|
|
public void EmitMethodEmitsInstance()
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
2017-09-29 15:50:30 +02:00
|
|
|
var class1 = new Class1();
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1> method1 = ReflectionUtilities.EmitMethod<Action<Class1>>("Method1");
|
2017-09-29 15:50:30 +02:00
|
|
|
method1(class1);
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1, int> method2 = ReflectionUtilities.EmitMethod<Action<Class1, int>>("Method2");
|
2017-09-29 15:50:30 +02:00
|
|
|
method2(class1, 42);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> method3 = ReflectionUtilities.EmitMethod<Func<Class1, int>>("Method3");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, method3(class1));
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, string, int> method4 = ReflectionUtilities.EmitMethod<Func<Class1, string, int>>("Method4");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, method4(class1, "42"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsStatic()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Action method1 = ReflectionUtilities.EmitMethod<Class1, Action>("SMethod1");
|
2017-09-29 15:50:30 +02:00
|
|
|
method1();
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<int> method2 = ReflectionUtilities.EmitMethod<Class1, Action<int>>("SMethod2");
|
2017-09-29 15:50:30 +02:00
|
|
|
method2(42);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<int> method3 = ReflectionUtilities.EmitMethod<Class1, Func<int>>("SMethod3");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, method3());
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<string, int> method4 = ReflectionUtilities.EmitMethod<Class1, Func<string, int>>("SMethod4");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, method4("42"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsStaticStatic()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Action method = ReflectionUtilities.EmitMethod<Action>(typeof(StaticClass1), "Method");
|
2017-09-29 15:50:30 +02:00
|
|
|
method();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsFromInfo()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
MethodInfo methodInfo = typeof(Class1).GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public);
|
|
|
|
|
Action<Class1> method1 = ReflectionUtilities.EmitMethod<Action<Class1>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
method1(class1);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
methodInfo = typeof(Class1).GetMethod("Method2", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(int) }, null);
|
|
|
|
|
Action<Class1, int> method2 = ReflectionUtilities.EmitMethod<Action<Class1, int>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
method2(class1, 42);
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("Method3", BindingFlags.Instance | BindingFlags.Public);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> method3 = ReflectionUtilities.EmitMethod<Func<Class1, int>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, method3(class1));
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("Method4", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(string) }, null);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, string, int> method4 = ReflectionUtilities.EmitMethod<Func<Class1, string, int>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, method4(class1, "42"));
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod1", BindingFlags.Static | BindingFlags.Public);
|
2020-12-20 08:36:11 +01:00
|
|
|
Action smethod1 = ReflectionUtilities.EmitMethod<Action>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
smethod1();
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod2", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(int) }, null);
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<int> smethod2 = ReflectionUtilities.EmitMethod<Action<int>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
smethod2(42);
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod3", BindingFlags.Static | BindingFlags.Public);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<int> smethod3 = ReflectionUtilities.EmitMethod<Func<int>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, smethod3());
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(Class1).GetMethod("SMethod4", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string) }, null);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<string, int> smethod4 = ReflectionUtilities.EmitMethod<Func<string, int>>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, smethod4("42"));
|
|
|
|
|
|
|
|
|
|
methodInfo = typeof(StaticClass1).GetMethod("Method", BindingFlags.Static | BindingFlags.Public);
|
2020-12-20 08:36:11 +01:00
|
|
|
Action method = ReflectionUtilities.EmitMethod<Action>(methodInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
method();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodEmitsPrivateMethod()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1> method1 = ReflectionUtilities.EmitMethod<Action<Class1>>("MethodP1");
|
2017-09-29 15:50:30 +02:00
|
|
|
method1(class1);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action method2 = ReflectionUtilities.EmitMethod<Class1, Action>("SMethodP1");
|
2017-09-29 15:50:30 +02:00
|
|
|
method2();
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodThrowsIfNotFound()
|
|
|
|
|
{
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitMethod<Action<Class1>>("ZZZ"));
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitMethod<Action<Class1, int, int>>("Method1"));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodThrowsIfInvalid()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
MethodInfo methodInfo = typeof(Class1).GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitMethod<Action<Class1, int, int>>(methodInfo));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitMethodReturnsNull()
|
|
|
|
|
{
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitMethod<Action<Class1>>("ZZZ", false));
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitMethod<Action<Class1, int, int>>("Method1", false));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyEmits()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> getter1 = ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value1");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter1(class1));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> getter2 = ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value3");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter2(class1));
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1, int> setter1 = ReflectionUtilities.EmitPropertySetter<Class1, int>("Value2");
|
2017-09-29 15:50:30 +02:00
|
|
|
setter1(class1, 42);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1, int> setter2 = ReflectionUtilities.EmitPropertySetter<Class1, int>("Value3");
|
2017-09-29 15:50:30 +02:00
|
|
|
setter2(class1, 42);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
(Func<Class1, int> getter3, Action<Class1, int> setter3) = ReflectionUtilities.EmitPropertyGetterAndSetter<Class1, int>("Value3");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter3(class1));
|
|
|
|
|
setter3(class1, 42);
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyEmitsFromInfo()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
PropertyInfo propertyInfo = typeof(Class1).GetProperty("Value1");
|
|
|
|
|
Func<Class1, int> getter1 = ReflectionUtilities.EmitPropertyGetter<Class1, int>(propertyInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter1(class1));
|
|
|
|
|
|
|
|
|
|
propertyInfo = typeof(Class1).GetProperty("Value3");
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> getter2 = ReflectionUtilities.EmitPropertyGetter<Class1, int>(propertyInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter2(class1));
|
|
|
|
|
|
|
|
|
|
propertyInfo = typeof(Class1).GetProperty("Value2");
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1, int> setter1 = ReflectionUtilities.EmitPropertySetter<Class1, int>(propertyInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
setter1(class1, 42);
|
|
|
|
|
|
|
|
|
|
propertyInfo = typeof(Class1).GetProperty("Value3");
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1, int> setter2 = ReflectionUtilities.EmitPropertySetter<Class1, int>(propertyInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
setter2(class1, 42);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
(Func<Class1, int> getter3, Action<Class1, int> setter3) = ReflectionUtilities.EmitPropertyGetterAndSetter<Class1, int>(propertyInfo);
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter3(class1));
|
|
|
|
|
setter3(class1, 42);
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyEmitsPrivateProperty()
|
|
|
|
|
{
|
|
|
|
|
var class1 = new Class1();
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> getter1 = ReflectionUtilities.EmitPropertyGetter<Class1, int>("ValueP1");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.AreEqual(42, getter1(class1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyThrowsIfNotFound()
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitPropertyGetter<Class1, int>("Zalue1"));
|
|
|
|
|
Assert.Throws<InvalidOperationException>(() => ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value2"));
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
PropertyInfo propertyInfo = typeof(Class1).GetProperty("Value1");
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitPropertySetter<Class1, int>(propertyInfo));
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
2020-12-20 08:36:11 +01:00
|
|
|
public void EmitPropertyThrowsIfInvalid() =>
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.Throws<ArgumentException>(() => ReflectionUtilities.EmitPropertyGetter<Class1, string>("Value1"));
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitPropertyReturnsNull()
|
2017-09-27 21:16:09 +02:00
|
|
|
{
|
2017-09-29 15:50:30 +02:00
|
|
|
Assert.IsNull(ReflectionUtilities.EmitPropertyGetter<Class1, int>("Zalue1", false));
|
|
|
|
|
Assert.IsNull(ReflectionUtilities.EmitPropertyGetter<Class1, int>("Value2", false));
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
[Test]
|
2018-06-07 14:29:31 +02:00
|
|
|
public void PropertySetterCanCastUnsafeValue()
|
2018-02-02 19:43:03 +01:00
|
|
|
{
|
|
|
|
|
// test that we can emit property setters that cast from eg 'object'
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type4 = typeof(Class4);
|
|
|
|
|
PropertyInfo propInt4 = type4.GetProperty("IntValue");
|
|
|
|
|
PropertyInfo propString4 = type4.GetProperty("StringValue");
|
|
|
|
|
PropertyInfo propClassA4 = type4.GetProperty("ClassAValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var object4 = new Class4();
|
|
|
|
|
var object2A = new Class2A();
|
|
|
|
|
|
|
|
|
|
// works with a string property
|
|
|
|
|
Assert.IsNotNull(propString4);
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class4, object> setterString4 = ReflectionUtilities.EmitPropertySetterUnsafe<Class4, object>(propString4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(setterString4);
|
|
|
|
|
setterString4(object4, "foo");
|
|
|
|
|
Assert.IsNotNull(object4.StringValue);
|
|
|
|
|
Assert.AreEqual("foo", object4.StringValue);
|
|
|
|
|
|
2018-03-01 14:50:42 +01:00
|
|
|
// unsafe is... unsafe
|
|
|
|
|
Assert.Throws<InvalidCastException>(() => setterString4(object4, new Class2()));
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
// works with a reference property
|
|
|
|
|
Assert.IsNotNull(propClassA4);
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class4, object> setterClassA4 = ReflectionUtilities.EmitPropertySetterUnsafe<Class4, object>(propClassA4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(setterClassA4);
|
|
|
|
|
setterClassA4(object4, object2A);
|
|
|
|
|
Assert.IsNotNull(object4.ClassAValue);
|
|
|
|
|
Assert.AreEqual(object2A, object4.ClassAValue);
|
|
|
|
|
|
2018-03-01 14:50:42 +01:00
|
|
|
// works with a boxed value type
|
|
|
|
|
Assert.IsNotNull(propInt4);
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class4, object> setterInt4 = ReflectionUtilities.EmitPropertySetterUnsafe<Class4, object>(propInt4);
|
2018-03-01 14:50:42 +01:00
|
|
|
Assert.IsNotNull(setterInt4);
|
|
|
|
|
|
|
|
|
|
setterInt4(object4, 42);
|
|
|
|
|
Assert.AreEqual(42, object4.IntValue);
|
|
|
|
|
|
2019-01-27 01:17:32 -05:00
|
|
|
// FIXME: the code below runs fine with ReSharper test running within VisualStudio
|
2018-06-07 14:29:31 +02:00
|
|
|
// but it crashes when running via vstest.console.exe - unless some settings are required?
|
|
|
|
|
|
2018-03-01 14:50:42 +01:00
|
|
|
// converting works
|
|
|
|
|
setterInt4(object4, 42.0);
|
|
|
|
|
Assert.AreEqual(42, object4.IntValue);
|
|
|
|
|
|
|
|
|
|
// unsafe is... unsafe
|
|
|
|
|
Assert.Throws<FormatException>(() => setterInt4(object4, "foo"));
|
2018-02-02 19:43:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2018-06-07 14:29:31 +02:00
|
|
|
public void PropertySetterCanCastObject()
|
2018-02-02 19:43:03 +01:00
|
|
|
{
|
2018-03-01 14:50:42 +01:00
|
|
|
// Class5 inherits from Class4 and ClassValue is defined on Class4
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type5 = typeof(Class5);
|
|
|
|
|
PropertyInfo propClass4 = type5.GetProperty("ClassValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var object2 = new Class2();
|
|
|
|
|
|
|
|
|
|
// can cast the object type from Class5 to Class4
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class5, Class2> setterClass4 = ReflectionUtilities.EmitPropertySetter<Class5, Class2>(propClass4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2018-03-01 14:50:42 +01:00
|
|
|
var object4 = new Class5();
|
|
|
|
|
setterClass4(object4, object2);
|
|
|
|
|
Assert.IsNotNull(object4.ClassValue);
|
|
|
|
|
Assert.AreSame(object2, object4.ClassValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2018-06-07 14:29:31 +02:00
|
|
|
public void PropertySetterCanCastUnsafeObject()
|
2018-03-01 14:50:42 +01:00
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type5 = typeof(Class5);
|
|
|
|
|
PropertyInfo propClass4 = type5.GetProperty("ClassValue");
|
2018-03-01 14:50:42 +01:00
|
|
|
|
|
|
|
|
var object2 = new Class2();
|
|
|
|
|
|
|
|
|
|
// can cast the object type from object to Class4
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<object, Class2> setterClass4 = ReflectionUtilities.EmitPropertySetterUnsafe<object, Class2>(propClass4);
|
2018-03-01 14:50:42 +01:00
|
|
|
|
|
|
|
|
var object4 = new Class5();
|
2018-02-02 19:43:03 +01:00
|
|
|
setterClass4(object4, object2);
|
|
|
|
|
Assert.IsNotNull(object4.ClassValue);
|
|
|
|
|
Assert.AreSame(object2, object4.ClassValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2018-06-07 14:29:31 +02:00
|
|
|
public void PropertyGetterCanCastValue()
|
2018-02-02 19:43:03 +01:00
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type4 = typeof(Class4);
|
|
|
|
|
PropertyInfo propClassA4 = type4.GetProperty("ClassAValue");
|
|
|
|
|
PropertyInfo propInt4 = type4.GetProperty("IntValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var object2A = new Class2A();
|
|
|
|
|
var object4 = new Class4 { ClassAValue = object2A, IntValue = 159 };
|
|
|
|
|
|
|
|
|
|
// can cast the return type from Class2A to Class2
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class4, Class2> getterClassA4 = ReflectionUtilities.EmitPropertyGetter<Class4, Class2>(propClassA4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Class2 valueClass4A = getterClassA4(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(valueClass4A);
|
|
|
|
|
Assert.AreSame(object2A, valueClass4A);
|
|
|
|
|
|
|
|
|
|
// cannot cast the return type from Class2A to Class3!
|
|
|
|
|
Assert.Throws<ArgumentException>(()
|
|
|
|
|
=> ReflectionUtilities.EmitPropertyGetter<Class4, Class3>(propClassA4));
|
|
|
|
|
|
|
|
|
|
// can cast and box the return type from int to object
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class4, object> getterInt4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propInt4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
object valueInt4 = getterInt4(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsTrue(valueInt4 is int);
|
|
|
|
|
Assert.AreEqual(159, valueInt4);
|
|
|
|
|
|
|
|
|
|
// cannot cast the return type from int to Class3!
|
|
|
|
|
Assert.Throws<ArgumentException>(()
|
|
|
|
|
=> ReflectionUtilities.EmitPropertyGetter<Class4, Class3>(propInt4));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2018-06-07 14:29:31 +02:00
|
|
|
public void PropertyGetterCanCastObject()
|
2018-02-02 19:43:03 +01:00
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type5 = typeof(Class5);
|
|
|
|
|
PropertyInfo propClass4 = type5.GetProperty("ClassValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var object2 = new Class2();
|
|
|
|
|
var object4 = new Class5 { ClassValue = object2 };
|
|
|
|
|
|
|
|
|
|
// can cast the object type from Class5 to Class4
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class5, Class2> getterClass4 = ReflectionUtilities.EmitPropertyGetter<Class5, Class2>(propClass4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Class2 valueClass4 = getterClass4(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(valueClass4);
|
|
|
|
|
Assert.AreSame(object2, valueClass4);
|
|
|
|
|
|
|
|
|
|
// cannot cast the object type from Class3 to Class4!
|
|
|
|
|
Assert.Throws<ArgumentException>(()
|
|
|
|
|
=> ReflectionUtilities.EmitPropertyGetter<Class3, Class2>(propClass4));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2018-06-07 14:29:31 +02:00
|
|
|
public void EmitPropertyCastGetterEmits()
|
2018-02-02 19:43:03 +01:00
|
|
|
{
|
|
|
|
|
// test that we can emit property getters that cast the returned value to 'object'
|
|
|
|
|
// test simple class
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type4 = typeof(Class4);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var object4 = new Class4
|
|
|
|
|
{
|
|
|
|
|
IntValue = 1,
|
|
|
|
|
StringValue = "foo",
|
|
|
|
|
ClassValue = new Class2(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// works with a string property
|
2020-12-20 08:36:11 +01:00
|
|
|
PropertyInfo propString4 = type4.GetProperty("StringValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(propString4);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class4, object> getterString4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propString4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(getterString4);
|
2020-12-20 08:36:11 +01:00
|
|
|
object valueString4 = getterString4(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(valueString4);
|
|
|
|
|
Assert.AreEqual("foo", valueString4);
|
|
|
|
|
|
|
|
|
|
// works with a reference property
|
2020-12-20 08:36:11 +01:00
|
|
|
PropertyInfo propClass4 = type4.GetProperty("ClassValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(propClass4);
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class4, object> getterClass4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propClass4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(getterClass4);
|
2020-12-20 08:36:11 +01:00
|
|
|
object valueClass4 = getterClass4(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(valueClass4);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(valueClass4);
|
|
|
|
|
|
|
|
|
|
// works with a value type property
|
2020-12-20 08:36:11 +01:00
|
|
|
PropertyInfo propInt4 = type4.GetProperty("IntValue");
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(propInt4);
|
|
|
|
|
|
2020-05-03 15:51:46 +01:00
|
|
|
// ... if explicitly getting a value type
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class4, int> getterInt4T = ReflectionUtilities.EmitPropertyGetter<Class4, int>(propInt4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(getterInt4T);
|
2020-12-20 08:36:11 +01:00
|
|
|
int valueInt4T = getterInt4T(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.AreEqual(1, valueInt4T);
|
|
|
|
|
|
|
|
|
|
// ... if using a compiled getter
|
2020-12-20 08:36:11 +01:00
|
|
|
object valueInt4D = GetIntValue(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(valueInt4D);
|
|
|
|
|
Assert.IsTrue(valueInt4D is int);
|
|
|
|
|
Assert.AreEqual(1, valueInt4D);
|
|
|
|
|
|
|
|
|
|
// ... if getting a non-value type (emit adds a box)
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class4, object> getterInt4 = ReflectionUtilities.EmitPropertyGetter<Class4, object>(propInt4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(getterInt4);
|
2020-12-20 08:36:11 +01:00
|
|
|
object valueInt4 = getterInt4(object4);
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.IsNotNull(valueInt4);
|
|
|
|
|
Assert.IsTrue(valueInt4 is int);
|
|
|
|
|
Assert.AreEqual(1, valueInt4);
|
|
|
|
|
|
|
|
|
|
var getters4 = type4
|
|
|
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
|
2020-12-20 08:36:11 +01:00
|
|
|
.ToDictionary(x => x.Name, x => (object)ReflectionUtilities.EmitPropertyGetter<Class4, object>(x));
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
Console.WriteLine("Getting object4 values...");
|
2020-12-20 08:36:11 +01:00
|
|
|
var values4 = getters4.ToDictionary(kvp => kvp.Key, kvp => ((Func<Class4, object>)kvp.Value)(object4));
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
Console.WriteLine("Writing object4 values...");
|
2020-12-20 08:36:11 +01:00
|
|
|
foreach ((string name, object value) in values4)
|
|
|
|
|
{
|
2018-02-02 19:43:03 +01:00
|
|
|
Console.WriteLine($"{name}: {value}");
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.AreEqual(4, values4.Count);
|
|
|
|
|
Assert.AreEqual("foo", values4["StringValue"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values4["ClassValue"]);
|
|
|
|
|
Assert.AreEqual(1, values4["IntValue"]);
|
|
|
|
|
|
|
|
|
|
// test hierarchy
|
2020-12-20 08:36:11 +01:00
|
|
|
Type type5 = typeof(Class5);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var getters5 = type5
|
|
|
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
|
2020-12-20 08:36:11 +01:00
|
|
|
.ToDictionary(x => x.Name, x => (object)ReflectionUtilities.EmitPropertyGetter<Class5, object>(x));
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
var object5 = new Class5
|
|
|
|
|
{
|
|
|
|
|
IntValue = 1,
|
|
|
|
|
IntValue2 = 1,
|
|
|
|
|
StringValue = "foo",
|
|
|
|
|
StringValue2 = "foo",
|
|
|
|
|
ClassValue = new Class2(),
|
|
|
|
|
ClassValue2 = new Class2()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Getting object5 values...");
|
2020-12-20 08:36:11 +01:00
|
|
|
var values5 = getters5.ToDictionary(kvp => kvp.Key, kvp => ((Func<Class5, object>)kvp.Value)(object5));
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
Console.WriteLine("Writing object5 values...");
|
2020-12-20 08:36:11 +01:00
|
|
|
foreach ((string name, object value) in values5)
|
|
|
|
|
{
|
2018-02-02 19:43:03 +01:00
|
|
|
Console.WriteLine($"{name}: {value}");
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.AreEqual(7, values5.Count);
|
|
|
|
|
Assert.AreEqual("foo", values5["StringValue"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5["ClassValue"]);
|
|
|
|
|
Assert.AreEqual(1, values5["IntValue"]);
|
|
|
|
|
Assert.AreEqual("foo", values5["StringValue2"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5["ClassValue2"]);
|
|
|
|
|
Assert.AreEqual(1, values5["IntValue2"]);
|
|
|
|
|
|
|
|
|
|
// test object extensions
|
|
|
|
|
Console.WriteLine("Getting object5D values...");
|
2020-12-20 08:36:11 +01:00
|
|
|
Dictionary<string, object> values5D = ObjectJsonExtensions.ToObjectDictionary(object5);
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
Console.WriteLine("Writing object5D values...");
|
2020-12-20 08:36:11 +01:00
|
|
|
foreach ((string name, object value) in values5)
|
|
|
|
|
{
|
2018-02-02 19:43:03 +01:00
|
|
|
Console.WriteLine($"{name}: {value}");
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
Assert.AreEqual(7, values5.Count);
|
|
|
|
|
Assert.AreEqual("foo", values5D["StringValue"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5D["ClassValue"]);
|
|
|
|
|
Assert.AreEqual(1, values5D["IntValue"]);
|
|
|
|
|
Assert.AreEqual("foo", values5D["StringValue2"]);
|
|
|
|
|
Assert.IsInstanceOf<Class2>(values5D["ClassValue2"]);
|
|
|
|
|
Assert.AreEqual(1, values5D["intValue2"]); // JsonProperty changes property name
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-29 18:30:37 +02:00
|
|
|
[Test]
|
|
|
|
|
public void EmitFieldGetterSetterEmits()
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
Func<Class1, int> getter1 = ReflectionUtilities.EmitFieldGetter<Class1, int>("Field1");
|
|
|
|
|
Func<Class1, int> getter2 = ReflectionUtilities.EmitFieldGetter<Class1, int>("Field2");
|
2018-05-29 18:30:37 +02:00
|
|
|
var c = new Class1();
|
|
|
|
|
Assert.AreEqual(33, getter1(c));
|
|
|
|
|
Assert.AreEqual(66, getter2(c));
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
Action<Class1, int> setter2 = ReflectionUtilities.EmitFieldSetter<Class1, int>("Field2");
|
2018-05-29 18:30:37 +02:00
|
|
|
setter2(c, 99);
|
|
|
|
|
Assert.AreEqual(99, getter2(c));
|
|
|
|
|
|
|
|
|
|
// works on readonly fields!
|
2020-12-20 08:36:11 +01:00
|
|
|
(Func<Class1, int> getter3, Action<Class1, int> setter3) = ReflectionUtilities.EmitFieldGetterAndSetter<Class1, int>("Field3");
|
2018-05-29 18:30:37 +02:00
|
|
|
Assert.AreEqual(22, getter3(c));
|
|
|
|
|
setter3(c, 44);
|
|
|
|
|
Assert.AreEqual(44, getter3(c));
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-27 01:17:32 -05:00
|
|
|
// FIXME: missing tests specifying 'returned' on method, property
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2018-10-25 15:29:29 +02:00
|
|
|
[Test]
|
|
|
|
|
public void DeconstructAnonymousType()
|
|
|
|
|
{
|
|
|
|
|
var o = new { a = 1, b = "hello" };
|
|
|
|
|
|
|
|
|
|
var getters = new Dictionary<string, Func<object, object>>();
|
2020-12-20 08:36:11 +01:00
|
|
|
foreach (PropertyInfo prop in o.GetType().GetProperties())
|
|
|
|
|
{
|
2018-10-25 15:29:29 +02:00
|
|
|
getters[prop.Name] = ReflectionUtilities.EmitMethodUnsafe<Func<object, object>>(prop.GetMethod);
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
2018-10-25 15:29:29 +02:00
|
|
|
|
|
|
|
|
Assert.AreEqual(2, getters.Count);
|
|
|
|
|
Assert.IsTrue(getters.ContainsKey("a"));
|
|
|
|
|
Assert.IsTrue(getters.ContainsKey("b"));
|
|
|
|
|
Assert.AreEqual(1, getters["a"](o));
|
|
|
|
|
Assert.AreEqual("hello", getters["b"](o));
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
// these functions can be examined in eg DotPeek to understand IL works
|
|
|
|
|
|
|
|
|
|
// box [mscorlib]System.Int32
|
|
|
|
|
public object GetIntValue(Class4 object4) => object4.IntValue;
|
|
|
|
|
|
|
|
|
|
// unbox.any [mscorlib]System.Int32
|
2020-12-20 08:36:11 +01:00
|
|
|
public void SetIntValue(Class4 object4, object i) => object4.IntValue = (int)i;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
// castclass [mscorlib]System.String
|
2020-12-20 08:36:11 +01:00
|
|
|
public void SetStringValue(Class4 object4, object s) => object4.StringValue = (string)s;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
// conv.i4
|
2020-12-20 08:36:11 +01:00
|
|
|
public void SetIntValue(Class4 object4, double d) => object4.IntValue = (int)d;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2018-03-01 14:50:42 +01:00
|
|
|
// unbox.any [mscorlib]System.Double
|
2018-02-02 19:43:03 +01:00
|
|
|
// conv.i4
|
2020-12-20 08:36:11 +01:00
|
|
|
public void SetIntValue2(Class4 object4, object d) => object4.IntValue = (int)(double)d;
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2018-06-07 14:29:31 +02:00
|
|
|
public void SetIntValue3(Class4 object4, object v)
|
|
|
|
|
{
|
|
|
|
|
if (v is int i)
|
2020-12-20 08:36:11 +01:00
|
|
|
{
|
2018-06-07 14:29:31 +02:00
|
|
|
object4.IntValue = i;
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
2018-06-07 14:29:31 +02:00
|
|
|
else
|
2020-12-20 08:36:11 +01:00
|
|
|
{
|
2018-06-07 14:29:31 +02:00
|
|
|
object4.IntValue = Convert.ToInt32(v);
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
2018-06-07 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetIntValue4(Class4 object4, object v)
|
|
|
|
|
{
|
|
|
|
|
if (v is int i)
|
2020-12-20 08:36:11 +01:00
|
|
|
{
|
2018-06-07 14:29:31 +02:00
|
|
|
object4.IntValue = i;
|
2020-12-20 08:36:11 +01:00
|
|
|
}
|
2018-06-07 14:29:31 +02:00
|
|
|
else
|
2020-12-20 08:36:11 +01:00
|
|
|
{
|
|
|
|
|
object4.IntValue = (int)Convert.ChangeType(v, typeof(int));
|
|
|
|
|
}
|
2018-06-07 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-29 18:30:37 +02:00
|
|
|
// get field
|
|
|
|
|
public int GetIntField(Class1 object1) => object1.Field1;
|
|
|
|
|
|
|
|
|
|
// set field
|
|
|
|
|
public void SetIntField(Class1 object1, int i) => object1.Field1 = i;
|
|
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
public static class StaticClass1
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
public static void Method()
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
public class Class1
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
public Class1()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Class1(int i)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Method1()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Method2(int i)
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
|
|
|
|
public int Method3() => 42;
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
public int Method4(string s) => int.Parse(s);
|
|
|
|
|
|
|
|
|
|
public string Method5() => "foo";
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
public static void SMethod1()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void SMethod2(int i)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
public static int SMethod3() => 42;
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
public static int SMethod4(string s) => int.Parse(s);
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
private void MethodP1()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SMethodP1()
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
|
|
|
|
public int Value1 => 42;
|
2020-12-20 08:36:11 +01:00
|
|
|
|
|
|
|
|
public int Value2
|
|
|
|
|
{
|
|
|
|
|
set { }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Value3
|
|
|
|
|
{
|
|
|
|
|
get => 42; set { }
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
private int ValueP1 => 42;
|
2018-05-29 18:30:37 +02:00
|
|
|
|
|
|
|
|
public int Field1 = 33;
|
|
|
|
|
private int Field2 = 66;
|
|
|
|
|
public readonly int Field3 = 22;
|
2017-09-29 15:50:30 +02:00
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
public class Class2
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
public class Class2A : Class2
|
|
|
|
|
{
|
|
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
2017-09-29 15:50:30 +02:00
|
|
|
public class Class3
|
|
|
|
|
{
|
2020-12-20 08:36:11 +01:00
|
|
|
public Class3(int i)
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
private Class3(string s)
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-09-29 15:50:30 +02:00
|
|
|
}
|
2018-02-02 19:43:03 +01:00
|
|
|
|
|
|
|
|
public class Class4
|
|
|
|
|
{
|
|
|
|
|
public int IntValue { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
public string StringValue { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
|
|
|
|
public Class2 ClassValue { get; set; }
|
|
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
public Class2A ClassAValue { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Class5 : Class4
|
|
|
|
|
{
|
|
|
|
|
[JsonProperty("intValue2")]
|
|
|
|
|
public int IntValue2 { get; set; }
|
2020-12-20 08:36:11 +01:00
|
|
|
|
2018-02-02 19:43:03 +01:00
|
|
|
public string StringValue2 { get; set; }
|
|
|
|
|
|
2020-12-20 08:36:11 +01:00
|
|
|
public Class2 ClassValue2 { get; set; }
|
|
|
|
|
}
|
2017-09-27 21:16:09 +02:00
|
|
|
}
|
|
|
|
|
}
|