Implementing C# EventHandlers in F# - c#

I have an interface, written in C#, defined as this :
public interface IWidget
{
object Evaluate();
event EventHandler Invalidated;
}
When I try to implement this interface in F#, I look at what F# thinks the IWidget interface is (by hovering my mouse over it), and I see
type IWidget =
interface
member Evaluate : unit -> obj
end
It appears to ignore the Invalidated event entirely... is this a known issue with F# and if so is there any way to work around it? When implementing my F# version of IWidget, can I just implement this event outside of the IWidget section or what? It seems really nasty that f# handles the "event" keyword so poorly...
UPDATE:
After further fiddling around, studio was then saying things like:
'no implementation was given for IWidget.remove_Invalidate(value:EventHandler):unit'
then, when I added those methods so the whole thing looked like:
interface IWidget with
member w.Evaluate() = new obj()
member w.add_Invalidated(value:EventHandler) = ()
member w.remove_Invalidated(value:EventHandler) = ()
end
it compiled fine, even though the tooltip was still saying the only member of IWidget was Evaluate()... it seems like the way F# (or at least the IDE) handles this stuff is really screwy...
ANOTHER UPDATE:
According to the tooltip in the IDE, the [] tag allows an event to be compiled as a CLI metadata event, by transforming it to a pair of add_/remove_ methods... just FYI for anyone who was as confused by this as I was. In short, either implementing those two methods or using that tag work fine, though the fact that the tooltip view of the IWdiget interface lacks any mention of the Invalidate event, and the necessity of implementing such an event is only noticed when the compiler throws an error, is still a clear bug and is pretty confusing. For anyone curious, the following code works fine:
let invalidated = new DelegateEvent<System.EventHandler>()
interface IWidget with
member w.Evaluate() = new obj()
[<CLIEvent>]
member w.Invalidated = invalidated.Publish
end
Thanks for all the help everyone!

F# does support events.
For example:
let invalidated = new DelegateEvent<System.EventHandler>()
[<CLIEvent>]
member this.Invalidated = invalidated.Publish

Related

How do define an event in F# visible from C#

Looking at various bits of documentation, the way of defining an event in F# is to do something like
type xyz () =
let e = new Event<T>
member x.something_happened : IEvent<T> = x.Publish
Unfortunately, the type of IEvent is really Miscrosoft.FSharp.Control.IEvent<_>, and it is hence difficult to use from within C#. Some articles suggest adding the CLIEvent attribute to member something_happended above but it seems to make no difference as far as its usability from C# without including the F# library goes.
How do I correctly define an event in F# so I can then add a delegate to it in C# code? Many thanks.
There are two event types in F#, Event<'T> and Event<'Delegate, 'Args>. Only the second one is compiled to a .NET event when [<CLIEvent>] is present. Here's a working example:
type T() =
let e = Event<EventHandler<_>,_>()
[<CLIEvent>]
member x.MyEvent = e.Publish
member x.RaiseMyEvent() = e.Trigger(x, EventArgs.Empty)
In some cases the compiler generates a warning if [<CLIEvent>] is used with a non-standard event type. I'm not sure why it doesn't raise a warning for your code (perhaps a bug?).

Getting a managed callback from a WRL COM component

The Background (Or, look how far I've gone on my own!)
I'm starting from the Windows 8 Media Extension Sample. I'm using the grayscale example as a starting point to learn how to pass values from managed code into a COM object, and how to pass values from my COM object back to managed code. In my IDL file, I've got a GrayscaleEffect class (taken exactly from the example) and a custom interface that should let me query a string over in the c# world.
The IDL file:
namespace GrayscaleTransform
{
[version(NTDDI_WIN8), uuid(553B5684-4C22-4D21-8638-1E7D86D84F10)]
interface MyInterface : IInspectable {
HRESULT GetMsg([out] HSTRING *message);
}
[version(NTDDI_WIN8)]
runtimeclass GrayscaleEffect {
interface Windows.Media.IMediaExtension;
interface MyInterface;
}
}
My GrayscaleEffect class implementation implements GetMsg to return the string "Woozle"
The relevant c#:
cap = new MediaCapture();
await cap.InitializeAsync();
previewElement1.Source = cap;
await cap.StartPreviewAsync();
PropertySet props = new PropertySet();
await cap.AddEffectAsync(
Windows.Media.Capture.MediaStreamType.VideoPreview,
"GrayscaleTransform.GrayscaleEffect",
props);
if (this.props.ContainsKey("ref"))
{
var augGui = (GrayscaleTransform.MyInterface)this.props["ref"];
string message;
augGui.GetMsg(out message);
}
After the call to GetMsg, I can see that message contains the string "Woozle" just like I expect - Excellent!
The Problem
Now I want to do something a little bit fancier. Instead of a method that lets me pass a string from COM to C#, I want to implement a method that lets me pass a delegate from C# to COM. I'd like to get the MFT class to call this method every 10th video frame or something - that part's not important. I want my interface to have a method called SubscribeEvent that takes a delegate as a parameter. For now, it can be a void delegate that takes no arguments.
This page leads me to believe that I should be able to declare a WinRT delegate over in the COM world and be able to pass a delegate of the same type from C# (see the 3rd item from the end). Cool - seems easy. My best try so far has been something like this in the idl:
delegate void CallbackMethod();
[version(NTDDI_WIN8), uuid(553B5684-4C22-4D21-8638-1E7D86D84F10)]
interface MyInterface : IInspectable {
HRESULT Subscribe(CallbackMethod cb);
}
Unfortunately this results in an error - seems to be related to the declaration of the delegate CallbackMethod:
error MIDL9008: internal compiler problem - See documentation for suggestions on how to find a workaround.
Edit
This one is obvious. That syntax is a C++/cx thing. Upon closer inspection, I don't have the C++/CX extensions turned on. This is a WRL project which means it's regular flavor c++ with template magic.
I also tried to wire up an event by implementing the IConnectionPoint interface, but when I include OCIdl.h I get a compile error that desktop components cannot be compiled for ARM.
The Question
Am I barking up the wrong tree here? Should I be making my GrayscaleEffect class be a WinRT runtime class using C++/CX? Maybe we're venturing into "New question" territory here, but when I try to implement IMFTransform with a WinRT class in C++/CX, I get
error C2811: 'GrayscaleRT::Class1' : cannot inherit from 'IMFTransform', a ref class can only inherit from a ref class or interface class
A better question:
How about this: Can I pass a delegate here at all? I fell like I ought to be able to, if only I knew the magic combination of WRL templates to make it work.
It looks like this is the answer. In WRL, you declare an event in your idl like this:
[uuid(3FBED04F-EFA7-4D92-B04D-59BD8B1B055E), version(NTDDI_WIN8)]
delegate HRESULT WhateverEvent();
See the To add an event that fires when a prime number is calculated section
My problem was that I initially didn't understand that I wasn't using c++/cx. I was using regular c++ with WRL which is a template library similar to ATL that makes WinRT programming easier and doesn't use non-standard language extensions.
Once I understood that, it was relatively easy to find an example of an event handler using WRL

Dynamically create or set the return type of a function in the function

I am attempting to create a function where the return type is determined at run-time. I know I could just return an object or dynamic, however my aim is to have the typed object returned, and be recognized by the compiler and InteliSense.
I know I could cast my object after it has been returned and that would be the easiest thing to do to implement this, but that is just not the programming spirit.
Here is an example of what I'm trying to create
Note: I do not actually want Buttons and Grids... that is just for this example.
Type T;
public T Question(bool aBool)
{
if (aBool)
{
T = typeof(Button);
return new Button();
}
else
{
T = typeof(Grid);
return new Grid();
}
}
Now, this obviously doesn't work and I understand why. But I want to know if anyone has a way that does work, or if this is not possible with the current state of C#.
Edit: A response to comments... I understand this would seem like "magic", and I do understand that the compiler will have to figure out what my result is for this to work. The compiler/Intellisense/Visual Studio already does this for many other things. While these things are can simple like detecting unreachable code, or drawing visual previews. I am curious if this is an implemented feature.
The only possible way for the consumer of such a method to actually rely on the fact that the return type is dynamic is if, at least for that one method call, the return type is statically known at compile time.
There is a specific feature for a method that has some type unknown at the time the method is written, but fixed when a particular call to that method is make. That feature is called "generics".
public T Foo<T>()
where T : new()
{
return new T();
}
That's really the only available option for a truly dynamic return type that has much potential for really being useful.
If that's not what you want, or that is not a workable option for you, then odds are pretty high your method shouldn't have a dynamically changing return type. Instead it should have a fixed return type of some more generalized type that can have multiple implementations. Generally this would mean an interface, to which you can return one of any number of possible implementations. This should be done if the caller doesn't need to really know or care what the implementation is, but rather all they need to know is that they are given some implementation of an interface that exposes all of what they need. In your case, perhaps something like Control would be workable, if the caller only need to know that they are given some type of control, and to which the API of Control provides everything that they need to do with it.
You can use Dynamic keyword in this case
eg:
public dynamic CreatObj(string caller)
{
if (caller.equals("x"))
return x;
else
return y;
}
You can use a type if it has a parameterless constructor and you mark your generic with the new constraint. If you want to do more than that it get more difficult you need to use refection or activator.

Verifying code against template patterns using reflection

I am working on a large project where a base class has thousands of classes derived from it (multiple developers are working on them). Each class is expected to override a set of methods. I first generated these thousands of class files with a code template that conforms to an acceptable pattern. I am now writing unit tests to ensure that developers have not deviated from this pattern. Here is a sample generated class:
// Base class.
public abstract partial class BaseClass
{
protected abstract bool OnTest ();
}
// Derived class. DO NOT CHANGE THE CLASS NAME!
public sealed partial class DerivedClass_00000001: BaseClass
{
/// <summary>
/// Do not modify the code template in any way.
/// Write code only in the try and finally blocks in this method.
/// </summary>
protected override void OnTest ()
{
bool result = false;
ComObject com = null;
// Declare ALL value and reference type variables here. NOWHERE ELSE!
// Variables that would otherwise be narrowly scoped should also be declared here.
// Initialize all reference types to [null]. [object o;] does not conform. [object o = null;] conforms.
// Initialize all value types to their default values. [int x;] does not conform. [int x = 0;] conforms.
try
{
com = new ComObject();
// Process COM objects here.
// Do NOT return out of this function yourself!
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
}
return (result);
}
}
In the unit tests, I have been able to verify the following via reflection:
The class derives from [BaseClass] and does not implement any interfaces.
The class name conforms to a pattern.
The catch block has not been filtered.
No other catch blocks have been added.
No class level fields or properties have been declared.
All method value type variables have been manually initialized upon declaration.
No other methods have been added to the derived classes.
The above is easily achieved via reflection but I am struggling with asserting the following list:
The catch block re-throws the caught exception rather than wrapping it or throwing some other exception.
The [return (result);] line at the end has not been modified and no other [return (whatever);] calls have been added. No idea how to achieve this.
Verify that all reference types implementing IDisposable have been disposed.
Verify that all reference types of type [System.__ComObject] have been manually de-referenced and set to [null] in the finally block.
I have thought about parsing the source code but I don't like that solution unless absolutely necessary. It is messy and unless I have expression trees, almost impossible to guarantee success.
Any tips would be appreciated.
Some thoughts:
If the methods need to be overriden, why are they virtual instead of abstract?
Code that should not be changed doesn't belong in the derived class. It belongs in the base class.
catch { throw; } is useless. Remove it.
Returning a boolean value from a void method causes a compiler error.
Setting local variables to null is useless.
Not all reference types implement IDisposable.
Generally: Most of your requirements seem to have no business value.
Why prohibit implementation of an interface?
Why prohibit declaration of other methods?
Why prohibit catch clauses?
etc.
You should really think about what your actual business requirements are and model your classes after them. If the classes need to fulfill a certain contract, model that contract. Leave the implementation to the implementor.
About the actual questions raised:
You can't use reflection here. You can either analyze the original source code or the IL code of the compiled assembly.
Both options are pretty tricky and most likely impossible to achieve within your limited time. I am positive that fixing the architecture would take less time than implementing one of those options.
You could try to use Roslyn CTP here if the fully automated code analysis is what you really need. It has more advanced syntax and semantics analysis than reflection does. But it is still a lot of work. Working directly with developers, not with their code, preparing templates, guidelines may be more time efficient.
While I'm sure you have a very good reason for such rigid requirements... have you considered passing a Lambda's/Delegates/Action to the Test function instead?
Can't solve everything, but would more logically give you some of the behaviours you want (e.g. can't return, can't have class level variables, can't write code anywhere but specified).
Biggest concern with it would be captured variables... but there may be work arounds for that.
Example Code:
//I'd make a few signatures....
bool OnTest<T1, T2> (Action<ComObject, T1, T2> logic, T1 first, T2 second)
{
bool result = false;
ComObject com = null;
//no checks needed re parameters
//Can add reflection tests here if wanted before code is run.
try
{
com = new ComObject();
//can't return
logic(com, first,second);
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
//If you want, we can check each argument and if it is disposable dispose.
if (first is IDisposable && first != null) ((IDisposable) first).Dispose();
...
}
return (result); //can't be changed
}
No idea if this'll work, but it's just a thought. Oh, and as a thought it's not thorough or tested - I'd expect you to develop it drastically.

Using Closures to keep track of a variable: Good idea or dirty trick?

Ok, i have a need to be able to keep track of value type objects which are properties on another object, which cannot be done without having those properties implement an IObservable interface or similar. Then i thought of closures and the famous example from Jon Skeet and how that prints out 9 (or 10) a bunch of times and not an ascending order of numbers. So i thought why not do this:
Class MyClass
{
...
Func<MyValueType> variable;
...
public void DoSomethingThatGetsCalledOften()
{
MyValueType blah = variable(); //error checking too not shown for brevity
//use it
}
...
}
... in some other consuming code ...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
//then myClass will get the current value of the variable whenever it needs it
Obviously this would require some understanding of how closures work, but my question is this: is this a good idea or a dirty hack and a misuse of the closure system?
Edit: Since some people seem to be misunderstanding what i'm trying to say, here's a console program which demonstrates it:
using System;
using System.Linq;
namespace Test
{
class Program
{
public static void Main()
{
float myFloat = 5;
Func<float> test = () => myFloat;
Console.WriteLine(test());
myFloat = 10;
Console.WriteLine(test());
Console.Read();
}
}
}
That will print out 5 then 10.
You have stumbled upon the famous koan: Closures are a poor man's object. You are using Action<T> to substitute for a property getter of type T. Such a thing would be (slightly) less of a dirty trick in a more dynamic language, since it could be implemented by injecting a getter that’s decorated with your logging function, but in C# there isn’t an elegant way to monkeypatch someone’s property when they’re not expecting it.
As a mechanism for obtaining the value fro a property, it'll work (but it won't provide any mechanism for noticing updates promptly). However, it depends on how you intend to use it. To do this conveniently you'll need to use a pile of lambdas in the code, or have some DynamicMethod / Expression code do it at runtime. In most cases, something more similar to reflection would be more convenient.
I wouldn't necessarily worry about the "value type" aspect; in most cases this isn't a bottleneck, despite the FUD - and it is generally a lot easier to handle such code with object than it is via generics or similar.
I have some code in my IDE that demonstrates DynamicMethod vs raw reflection (that I intend to blog some day soon), showing how reflection-based code doesn't have to be slow (or just use HyperDescriptor).
The other option is to implement the correct interfaces / add the correct events. Perhaps via PostSharp, perhaps via dynamic types (inheriting and overriding at runtime), perhaps with regular code.
You would need to type your variable member as Func<MyValueType> (or another delegate that returns MyValueType), but you wouldn't be able to assign the value of blah in that manner. Just as with using the closure in the foreach loop above, it's only going to evaluate at a point in time. This isn't a way to keep your variable's value in sync with the other object. There is, in fact, no way to do that without either:
continuously monitoring the value of the other instance's property in some sort of loop, like a Timer
implementing a change notification event on the other instance's class
You would be able to implement a property like that (since a property is evaluated at every call), but then what's the sense in using a custom delegate, other than the fact that you don't have to know anything about the other instance.
Edit
I'll try to make this a little clearer. Using this code that you posted:
Class MyClass
{
...
Action<MyValueType> variable;
...
MyValueType blah = variable();
//use it
...
}
...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
First, for this to be functional, variable should be Func<MyValueType>, not Action<MyValueType> (Func returns a value, Action does not; since you're trying to assign a value to a variable, you need the expression to return a value).
Second, the main issue with your approach is--assuming I'm reading your code correctly--you're attempting to assign the value of the instance variable blah to the evaluated value of variable() within the class declaration. This won't work for a couple of reasons:
assignments within class declarations cannot access instance members (which variable is)
the assignment of a variable within a class declaration just occurs upon construction of the object. Even if the first condition were present, you would simply get a NullReferenceException upon instantiating your object, since it would be trying to evaluate variable, which would be null at that time
even disregarding the first two, the value of blah would still only represent the evaluated value of variable() at whatever time it was evaluated. It would not "point to" that function and be automatically kept in sync, as it seems like you're trying to do.
If you aren't looking for some sort of automatic synchronization, then there's nothing stopping you from just keeping the Func<MyValueType> delegate around to evaluate; there's nothing particularly good or bad about that approach, and it isn't a closure unless the delegate (in your case a lambda expression) involves the use of a local variable.

Categories