Voldemort types in C# - c#

As you probably know in D language we have an ability called Voldemort Types and they are used as internal types that implement particular range function:
auto createVoldemortType(int value)
{
struct TheUnnameable
{
int getValue() { return value; }
}
return TheUnnameable();
}
Here is how the Voldemort type can be used:
auto voldemort = createVoldemortType(123);
writeln(voldemort.getValue()); // prints 123
Now I want to make sure that, Is this the equivalent to delegate in C#?
public static void Main()
{
var voldemort = createVoldemortType(123);
Console.WriteLine(voldemort());
}
public static Func<int> createVoldemortType(int value)
{
Func<int> theUnnameable = delegate()
{
return value;
};
return theUnnameable;
}

There isn't an exact equivalent of a Voldermort type in C#. The closest you have to such local scope classes is called Anonymous Types. Problem is, unlike Voldermort types, you can't refer to their static type at compile time outside of the local declaration:
public object SomeLocalMethod() // Must return either `dynamic` over `object`
{
var myAnonClass = new { X = 1, Y = "Hello" };
Console.WriteLine(myAnonClass.Y); // Prints "Hello";
return myAnonClass;
}
void Main()
{
object tryLookAtAnon = SomeLocalMethod(); // No access to "X" or "Y" variables here.
}
If however, we enter the land of dynamic, you can refer to the underlying class fields, but we lose type safety:
void Main()
{
dynamic tryLookAtAnon = SomeLocalMethod();
Console.WriteLine(tryLookAtAnon.X); // prints 1
}
public dynamic SomeLocalMethod()
{
var myAnonClass = new { X = 1, Y = "Hello" };
Console.WriteLine(myAnonClass.Y); // Prints "Hello";
return myAnonClass;
}
A delegate in C# is similar to a delegate in D. They hold a reference to a function.

Related

Compare Two Structs Using Standard Method (Byte Comparison/Reflection) Even If Equals Method Exists

I have some simple struct, which overrides the Equals() method:
public struct Pair<T> {
public Pair(T x, T y) {
X = x; Y = y;
}
public T X { get; }
public T Y { get; }
public override bool Equals(object obj) {
var otherPair = (Pair<T>) obj;
return X.Equals(otherPair.X);
}
}
According to MSDN, value types without an Equals() method are compared as follows:
If none of the fields of the current instance and obj are reference types, the Equals method performs a byte-by-byte comparison of the two objects in memory. Otherwise, it uses reflection to compare the corresponding fields of obj and this instance.
I wish to compare Pairs using the quoted approach instead of using Pair's own Equals() method, so that the following test passes:
[Test]
public void PairsEqual()
{
var p1a = new Pair<int>(10, 1);
var p1b = new Pair<int>(10, 1);
var p2 = new Pair<int>(10, 2);
Assert.That(p1a, Is.Not.EqualTo(p2));
Assert.That(p1a, Is.EqualTo(p1a));
Assert.That(p1a, Is.EqualTo(p1b));
}
This should ultimately work like a ReferenceEqual for structs. Is this possible? Ideally, I would like to replace the comparison with the original ValueType.Equals() method.
Edit:
My real wish is to be able to add a code contract to a class like this:
public class Holder<T> {
private T _item;
public Holder(T item) {
_item = item;
}
public T Item {
get { return _item; }
set {
Contract.Ensures(_item.Equals(value));
_item = value; // <-- imagine this like contained a bug
}
}
}
Imagine I use the holder object like this:
var holder = new Holder<Pair<int>>(p1a);
holder.Item = p2;
If set wasn't _item = value; but rather _item = _item;, the contract wouldn't complain, since the example would use Pair<T>'s Equals() method, which says that p1a and p2 are equal. If it instead use the original ValueType.Equals() method using byte comparison/reflection, the contract would have been violated correctly and the mistake would have been caugt.
Using objects, the contract would instead have been something like Contract.Ensures(ReferenceEqual(_item, value) but that doesn't work for value types (structs).
The point is that I don't know the type of T in Holder<T>, so I cannot introduce my own custom equality comparer, even if I wanted.
This can be done using reflection. The following solution is based on the code from the blog post Strong Typed, High Performance Reflection with C# Delegate, but the code has been shorten to work specifically for ValueType.Equals():
public static Func<ValueType, ValueType, bool> GetValueTypeEquals()
{
var type = typeof(ValueType);
var dynamicMethod = new DynamicMethod("ValueTypeEquals", typeof(bool), new[] { type, typeof(object) }, type);
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg, 0);
il.Emit(OpCodes.Ldarg, 1);
il.EmitCall(OpCodes.Call, type.GetMethod(nameof(Equals), Public | Instance, null, new[] { type }, null), null);
il.Emit(OpCodes.Ret);
return (Func<ValueType, ValueType, bool>) dynamicMethod.CreateDelegate(typeof(Func<ValueType, ValueType, bool>));
}
Using the method above to retrieve ValueTypes's Equal() method, the test from the example will look like this:
[Test]
public void PairsEqual()
{
var p1a = new Pair<int>(10, 1);
var p1b = new Pair<int>(10, 1);
var p2 = new Pair<int>(10, 2);
var equals = GetValueTypeEquals();
Assert.That(!equals(p1a, p2));
Assert.That(equals(p1a, p1a));
Assert.That(equals(p1a, p1b));
}

Dynamically declare a type for a method out parameter

I am struggling to describe this problem I have, but here it is:
Suppose I now have the type of a property on one member of a class (instance):
Type t = propertyInfo.PropertyType;
How do I declare or setup some variable, in order to receive a method call result later, using the out keyword?
t value; // Obviously doesn't compile, How do I declare this?
// or this?
//var value = default(t); // doesn't work
someObject.GetData(out value);
The premise here is that I don't own someObject and I am stuck with this method call signature.
If there is for example a class:
internal class Test
{
public void GetData(out int value)
{
value = 42;
}
}
The method can be called with Invoke() passing object[] as arguments:
var obj = new Test();
var type = obj.GetType();
var m = type.GetMethod("GetData");
var pars = new object[] { null };
m.Invoke(obj, pars);
I may be misunderstanding something about the complexity of the problem here, but, if you have a compile time instance of someObject, you can wrap the evil up like this:
class OutWrap<T,U> where T : U
{
private readonly SomeObject<T> obj;
public OutWrap(SomeObject<T> obj)
{
this.obj = obj;
}
public T Value
{
get
{
T t;
obj.GetData(out t);
return t;
}
}
}
and use it:
var evil = new SomeObject<int>(); // or however/whereever you get it from
var wrap = new OutWrap<int, int>(evil);
var output = wrap.Value;

How to declare a delegate that can take an enum which is not known until runtime?

I have a client application that uses classes (and enums) from an external dll which is loaded at runtime and reflected. I know what methods I am expecting to find in the dll and what I am expecting its enums to be called.
I would like to create a delegate that I can use in the client application and which is created from the reflected method at runtime. This approach works when the delegate just has "standard" types, but how can I get this to work if the dll method takes an enum? I can't declare the enum in the delegate as an object since it's a value type, trying the Enum or int does not seem to work either. Is there a way around this? Any help gratefully received!
// e.g. external code
namespace test2
{
public static class test2
{
public static int calc(int a, int b, testEnum c)
{
if (c == testEnum.add) return a + b;
else return a - b;
}
public static int add(int a, int b)
{
return a + b;
}
}
public enum testEnum
{
add, subtract
}
}
// my client code
namespace test1
{
public class TestClient
{
private static Assembly _assembly;
public static void SetUp()
{
const string externalDll = ".../test2.dll";
Assembly assembly = Assembly.LoadFrom(externalDll);
AppDomain.CurrentDomain.Load(assembly.GetName());
_assembly = assembly;
}
private delegate int _add(int a, int b);
private _add add;
private delegate int _calc(int a, int b, ??? c); // nothing works here
private _calc calc;
public void Run()
{
SetUp();
add = GetExpectedFunction<_add>("add");
int three = add(1, 2); // OK
calc = GetExpectedFunction<_calc>("calc"); // not OK
// intended usage
var reflectedEnum = ReflectMe("testEnum", "add");
int threeAgain = calc(1, 2, reflectedEnum);
}
public static T GetExpectedFunction<T>(string functionName) where T : class
{
try
{
if (!typeof(T).IsSubclassOf(typeof(Delegate))) throw new ApplicationException("GetExpectedFunction must return a delegate!");
var foundMethod = _assembly.GetType("test2.test2").GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
return (T)(object)Delegate.CreateDelegate(typeof(T), foundMethod);
}
catch (Exception e)
{
// "Error binding to target method!"
}
}
}
}
You can bind a delegate with object type to a method taking an enum by creating, at runtime, a dynamic method call with LINQ Expression, and adding data conversions for parameters whose types don't match:
public static T GetExpectedFunction<T>(string functionName) where T : class {
try {
if (!typeof(T).IsSubclassOf(typeof(Delegate))) throw new ApplicationException("GetExpectedFunction must return a delegate!");
var foundMethod = Type.GetType("test2.test2").GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
var inv = typeof(T).GetMethod("Invoke");
var parameters = inv.GetParameters().Zip(foundMethod.GetParameters(), (a, b) => new {
PassedIn = a.ParameterType
, Reflected = b.ParameterType
, Parameter = Expression.Parameter(a.ParameterType)
}).ToList();
if (parameters.All(p => p.PassedIn == p.Reflected)) {
// Bind directly
return (T)(object)Delegate.CreateDelegate(typeof(T), foundMethod);
}
var call = Expression.Call(foundMethod, parameters.Select(
p => p.PassedIn==p.Reflected
? (Expression)p.Parameter
: Expression.Convert(p.Parameter, p.Reflected)
));
return (T) (object) Expression.Lambda(typeof(T), call, parameters.Select(p => p.Parameter)).Compile();
} catch (Exception e) {
// "Error binding to target method!"
return null;
}
}
This implementation pairs up types from the reflected and the delegate methods (see parameters variable), and creates ParameterExpression objects for types that come from the delegate. Then it checks if all parameter types match up (the parameters.All(...) part). This is an optimization for situations when conversions are unnecessary.
If at least one conversion is necessary, the code creates a method call that substitutes the original parameter expressions with conversion expressions where types do not match up, creates a lambda of the requested delegate type, compiles it, and returns it to the caller.
For your code this dynamic method would look like this:
int dynamic_method(int a, int b, object c) {
return test2.test2(a, b, (testEnum)c);
}
There is one solution, you have to create faked Enum (it will be better if you create the exact enum), then you will pass as integer like this:
private delegate int _add(int a, int b);
private _add add;
private delegate int _calc(int a, int b, FakedEnum c); // faked enum here
private _calc calc;
public enum FakedEnum
{
}
public void Run()
{
SetUp();
add = GetExpectedFunction<_add>("add");
int three = add(1, 2); // OK
calc = GetExpectedFunction<_calc>("calc"); // it will be ok
var result= calc(4, 6, (FakedEnum)0);
// intended usage
// var reflectedEnum = ReflectMe("testEnum", "add");
//int threeAgain = calc(1, 2, reflectedEnum);
}
Use dynamic keyword to declare your delegate parameter:
private delegate int _calc(int a, int b, dynamic c);

Problem about Func<string>

class Program
{
static void Main()
{
int i = 0;
whatever x = new whatever(i);
Console.WriteLine(x);
i = 1;
Console.WriteLine(x);
Console.ReadKey();
}
class whatever
{
public whatever(object variable)
{
this.variable = () => variable.ToString();
}
private Func<string> variable;
public string data;
public override string ToString()
{
data = variable();
return data;
}
}
Output:
0
0
what I want to do is get updated i's value.
If you want to capture the local variable then you've put the lambda in the wrong place. The lambda has to go where it can be closed over the outer variable you want to capture.
class Program
{
static void Main()
{
int i = 0;
var x = new Whatever<int>(()=>i);
Console.WriteLine(x);
i = 1;
Console.WriteLine(x);
Console.ReadKey();
}
}
class Whatever<T>
{
private Func<T> variable;
public Whatever(Func<T> func)
{
this.variable= func;
}
public override string ToString()
{
return this.variable().ToString();
}
}
Does that make sense? See, the lambda has to be where the "i" is declared, so that "i" is an outer variable of the lambda and therefore the lambda sees changes to it.
i is an integer (value type), which is passed by value - a copy of the value is passed to the whatever constructor. When you change its value on the Main method, it doesn't change what has been already passed to the class. So you can't get the updated value on whatever.
If you have an object which holds a field of an integer value, and then pass that object to whatever, then changes to that field will be reflected on the class.
Maybe the problem is that delegate is bound to boxed integer data. This is why you change your int and delegate evaluates to old boxed data.
Try it with constructor that takes an int.
But, yes it's true that ints are pased by value, so this will not work.
Pass delegate to ctor.
class Program
{
static void Main()
{
int i = 0;
whatever x = new whatever(() => i.ToString());
Console.WriteLine(x);
i = 1;
Console.WriteLine(x);
Console.ReadKey();
}
class whatever
{
public whatever(Func<string> someFunc)
{
this.variable = someFunc;
}
private Func<string> variable;
public string data;
public override string ToString()
{
data = variable();
return data;
}
}
}
Output:
0
1
Or as other have indicated:
class Program
{
static void Main()
{
var myRefType = new MyRefType();
myRefType.MyInt = 0;
var x = new whatever(myRefType);
Console.WriteLine(x);
myRefType.MyInt = 1;
Console.WriteLine(x);
Console.ReadKey();
}
class whatever
{
public whatever(MyRefType myRefType)
{
this.variable = () => myRefType.MyInt.ToString();
}
private Func<string> variable;
public override string ToString()
{
return variable();
}
}
class MyRefType
{
public int MyInt { get; set; }
}
}
Outputs:
0
1
Integers are of value type, not reference type.
int is value type, meaning its value is copied each time you use it and not its reference. The best way to make this work is make reference type around int:
class IntRef
{
public int Val;
}
You will need to always use IntRef.Val and passing the IntVal itself around will retain the reference.

Instantiate an object with a runtime-determined type

I'm in a situation where I'd like to instantiate an object of a type that will be determined at runtime. I also need to perform an explicit cast to that type.
Something like this:
static void castTest(myEnum val)
{
//Call a native function that returns a pointer to a structure
IntPtr = someNativeFunction(..params..);
//determine the type of the structure based on the enum value
Type structType = getTypeFromEnum(val);
structType myStruct = (structType)Marshal.PtrToStructure(IntPtr, structType);
}
This is obviously not valid code, but I hope it conveys the essence of what I'm trying to do. The method I'm actually working on will have to perform the marshaling operation on ~35 different types. I have several other methods that will need to do something similar with the same set of types. So, I'd like to isolate the type-determining logic from these methods so that I only need to write it once, and so that the methods stay clean and readable.
I must admit to being a total novice at design. Could anyone suggest a good approach to this problem? I suspect there might be an appropriate design pattern that I'm unaware of.
There are several ways you can create an object of a certain type on the fly, one is:
// determine type here
var type = typeof(MyClass);
// create an object of the type
var obj = (MyClass)Activator.CreateInstance(type);
And you'll get an instance of MyClass in obj.
Another way is to use reflection:
// get type information
var type = typeof(MyClass);
// get public constructors
var ctors = type.GetConstructors(BindingFlags.Public);
// invoke the first public constructor with no parameters.
var obj = ctors[0].Invoke(new object[] { });
And from one of ConstructorInfo returned, you can "Invoke()" it with arguments and get back an instance of the class as if you've used a "new" operator.
You can mostly do what you're describing, but since you don't know the type at compile-time, you'll have to keep the instance loosely-typed; check its type at each point you use it, and cast it appropriately then (this will not be necessary with c# 4.0, which supports dynamics):
Type type = CustomGetTypeMethod();
var obj = Activator.CreateInstance(type);
...
if(obj is MyCustomType)
{
((MyCustomType)obj).Property1;
}
else if (obj is MyOtherCustomType)
{
((MyOtherCustomType)obj).Property2;
}
I think you're looking for Activator.CreateInstance
Creating an instance of a run-time determined Type is easy, using Activator.CreateInstance, as others have mentioned. However, casting it, as you do in your example on the Marshal.PtrToStructure line is not possible, as the type has to be known at compile time for casting. Also, note that Activator.CreateInstance can not be used in conjunction with an IntPtr.
If your types have a common base class (other than Object), you can cast it to said base type and call functions on that. Otherwise, calling functions will only be possible using reflection.
So either:
static void castTest(myEnum val)
{
//Call a native function that returns a pointer to a structure
IntPtr val = someNativeFunction(..params..);
//determine the type of the structure based on the enum value
Type structType = getTypeFromEnum(val);
BaseClass myStruct = (BaseClass)Marshal.PtrToStructure(IntPtr, structType);
myStruct.SomeFunctionDeclaredInBaseClass();
}
Or:
static void castTest(myEnum val)
{
//Call a native function that returns a pointer to a structure
IntPtr val = someNativeFunction(..params..);
//determine the type of the structure based on the enum value
Type structType = getTypeFromEnum(val);
object myStruct = Marshal.PtrToStructure(IntPtr, structType);
MemberInfo[] function = FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance,
(MemberFilter)delegate(MemberInfo info, object filter)
{
return info.Name == filter.ToString();
}, "SomeFunction");
if (mi.Length > 0 && mi[0] is MethodInfo)
((MethodInfo)mi[0]).Invoke(myStruct, ..params..);
}
You could go dynamic:
using System;
namespace TypeCaster
{
class Program
{
internal static void Main(string[] args)
{
Parent p = new Parent() { name = "I am the parent", type = "TypeCaster.ChildA" };
dynamic a = Convert.ChangeType(new ChildA(p.name), Type.GetType(p.type));
Console.WriteLine(a.Name);
p.type = "TypeCaster.ChildB";
dynamic b = Convert.ChangeType(new ChildB(p.name), Type.GetType(p.type));
Console.WriteLine(b.Name);
}
}
internal class Parent
{
internal string type { get; set; }
internal string name { get; set; }
internal Parent() { }
}
internal class ChildA : Parent
{
internal ChildA(string name)
{
base.name = name + " in A";
}
public string Name
{
get { return base.name; }
}
}
internal class ChildB : Parent
{
internal ChildB(string name)
{
base.name = name + " in B";
}
public string Name
{
get { return base.name; }
}
}
}
methodName = NwSheet.Cells[rCnt1, cCnt1 - 2].Value2;
Type nameSpace=typeof(ReadExcel);
Type metdType = Type.GetType(nameSpace.Namespace + "." + methodName);
//ConstructorInfo magicConstructor = metdType.GetConstructor(Type.EmptyTypes);
//object magicClassObject = magicConstructor.Invoke(new object[] { });
object magicClassObject = Activator.CreateInstance(metdType);
MethodInfo mthInfo = metdType.GetMethod("fn_"+methodName);
StaticVariable.dtReadData.Clear();
for (iCnt = cCnt1 + 4; iCnt <= ShtRange.Columns.Count; iCnt++)
{
temp = NwSheet.Cells[1, iCnt].Value2;
StaticVariable.dtReadData.Add(temp.Trim(), Convert.ToString(NwSheet.Cells[rCnt1, iCnt].Value2));
}
//if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_AddNum" || Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_SubNum")
//{
// //StaticVariable.intParam1 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 4].Value2);
// //StaticVariable.intParam2 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 5].Value2);
// object[] mParam1 = new object[] { Convert.ToInt32(StaticVariable.dtReadData["InParam1"]), Convert.ToInt32(StaticVariable.dtReadData["InParam2"]) };
// object result = mthInfo.Invoke(this, mParam1);
// StaticVariable.intOutParam1 = Convert.ToInt32(result);
// NwSheet.Cells[rCnt1, cCnt1 + 2].Value2 = Convert.ToString(StaticVariable.intOutParam1) != "" ? Convert.ToString(StaticVariable.intOutParam1) : String.Empty;
//}
//else
//{
object[] mParam = new object[] { };
mthInfo.Invoke(magicClassObject, mParam);

Categories