I have a need to define a custom routedeventarg in F# (to be used by both C# code and F# code).
In C#, I have defined the following
public class NewTranscriptEventArgs : RoutedEventArgs
{
private readonly string appendtext;
public string AppendText
{
get { return appendtext; }
}
public NewTranscriptEventArgs(RoutedEvent routedEvent, string appendtext) : base(routedEvent)
{
this.appendtext = appendtext;
}
}
I have no good idea on how this would be translated into F#.
Ultimately, the custom NewTranscriptEventArgs will be sent to the F# back-end by:
<i:EventTrigger EventName="NewTranscript">
<i:InvokeCommandAction PassEventArgsToCommand="True" Command="{Binding NewTranscript}" />
</i:EventTrigger>
Thanks for any help.
I haven't tried to run the code, but this is a literal translation to F#:
type NewTranscriptEventArgs(routedEvent, appendText : string) =
inherit RoutedEventArgs(routedEvent)
member _.AppendText = appendText
Ugh! How simple:
type NewTranscriptEventArgs(r:RoutedEvent, appendText: string ) =
inherit RoutedEventArgs(r)
member this.AppendText = appendText
Related
I used PowerMock to Mock Constructor.Afer launching the application,I thought all lines shoud be green.However,actually all lines are red.
I think Mocking Constructor results in this phenomenon.Beacause mocking others,like final classes, is OK.How to fix this problem?
//code:
public class People {
public String sayHello(){
return "hello";
}
}
public class Family {
public String doEvent() {
People p = new People();
String str = p.sayHello();
System.out.println(str);
return str;
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(Family.class)
public class FamilyTest {
#Test
public void test() throws Exception {
Family f = new Family();
String str = "hello mock";
People p = PowerMock.createMock(People.class);
PowerMock.expectNew(People.class).andReturn(p);
EasyMock.expect(p.sayHello()).andReturn(str);
PowerMock.replay(p, People.class);
String strActual = f.doEvent();
Assert.assertEquals(str, strActual);
PowerMock.verify(p, People.class);
}
}
You shouldn't have to use #PrepareForTest unless you are mocking static methods inside that class.
I believe your issue is that when you prepare a class for test using Powermocks runner, it does something funky with the byte code, which EclEmma uses for line coverage. Since you are not mocking any static methods in your family class, try removing that from your #PrepareForTest.
I am having difficulty to convert following C# code to F#:
class Foo
{
public Foo() { }
public Foo(string name) { }
}
class Bar : Foo
{
public Bar() : base() { }
public Bar(string name) : base(name) { }
public string Name { get; set; }
}
I first tried following, but it is reporting error
Constructors for the type 'Bar' must directly or indirectly call its
implicit object constructor. Use a call to the implicit object
constructor instead of a record expression.
type Foo() =
new(name:string) = Foo()
type Bar() =
inherit Foo()
new(name:string) = { inherit Foo(name) }
member val Name:string = null with get, set
Then I tried following, but it is now reporting error on the auto property
'member val' definitions are only permitted in types with a primary
constructor. Consider adding arguments to your type definition"
type Foo() =
new(name:string) = Foo()
type Bar =
inherit Foo
new(name:string) = { inherit Foo(name) }
member val Name:string = null with get, set
If you want F# source code who compiles to precisely the same API as given by your C# code, the answer is as follows:
type Foo =
new() = {}
new(name:string) = { }
type Bar =
inherit Foo
[<DefaultValue>]
val mutable private name:string
new() = { inherit Foo() }
new(name) = { inherit Foo(name) }
member x.Name with get() = x.name and set v = x.name <- v
This compiles:
type Foo() =
new(name:string) = Foo()
type Bar(name : string) =
inherit Foo()
new() = Bar(null) // or whatever you want as a default.
member val Name:string = name with get, set
See Constructors (F#) and Inheritance (F#).
Looking at the decompilation, the C# would be (with attributes removed):
public class Bar : Program.Foo {
internal string Name#;
public string Name {
get {
return this.Name#;
}
set {
this.Name# = value;
}
}
public Bar(string name) {
this.Name# = name;
}
public Bar() : this(null) {
}
}
public class Foo {
public Foo() {
}
public Foo(string name) : this() {
}
}
If a class has a parameter list directly after its name (including ()), it has a primary constructor. Using it, any inherit declarations are placed only in this primary constructor, which comes directly after the class declaration and before any member declarations.
It is unclear what you are trying to achieve. The class Foo has a constructor taking a string argument, only to discard it. A (technically) valid, similar pair of classes would be this:
type Foo(name:string) =
member f.NameLength = name.Length
type Bar(initialName) = // WARNING: this will not end well
inherit Foo(initialName)
member val Name:string = initialName with get, set
But this is not sensible code. Foo will keep the initial name even if the name in Bar is changed. Bar.Name.Length returns the current name's length, while Bar.NameLength returns the initial name's length.
To keep the default constructor, one could add new () = Bar(null) (or the equivalent in Foo), but please note that null is considered an interop-only feature. It is not used in F# facing code; if possible, use the appropriate option type or an empty string respectively (depending on whether the string is just empty or doesn't exist at all).
Also, inheriting classes is discouraged in the F# component design guidelines -- for good reason. There are few use cases, but those usually involve a tiny base class and a derived class that is a perfect superset of it. It is far more common to compose types by using one class as a member of another.
I don't know how relevant this is, but here is an example of a class with default constructor and an additional constructor that uses it:
type Text500(text : string) =
do if text.Length > 500 then
invalidArg "text" "Text of this type cannot have a length above 500."
member t.Text = text
new () = Text500("")
This utilizes the primary constructor to verify input and has an additional, parameterless constructor that uses an empty string. (I'm not sure if the additional constructor would be useful in actual applications.)
I have a code snippet here but i don't understand the use of "new (code)" in it.
type Product (code:string, price:float) =
let isFree = price=0.0
new (code) = Product(code,0.0)
member this.Code = code
member this.IsFree = isFree
Specifically why the need to enclose the "code" variable inside brackets.
That's a constructor. From MSDN: Classes (F#) (see section 'Constructors'):
You can add additional constructors by using the new keyword to add a member, as follows:
new (argument-list) = constructor-body
In your example, the Product type has one default constructor which accepts code and price, and one additional constructor that takes only code and applies the default constructor with 0.0 for price. In this case, the parentheses around code are not strictly required, and the code would compile just the same without it, although it would be required if you want constructor that takes zero parameters or more than one parameter.
The equivalent C# would be something like this:
public class Product
{
private string code;
private bool isFree;
public Product(string code, double price) {
this.code = code;
this.isFree = price == 0.0;
}
public Product(string code) : this(code, 0.0) { }
public string Code { get { return this.code; } }
public float IsFree { get { return this.isFree; } }
}
Pretty much as the title says: If you have a Type stored in a variable, there's no way to compare your actual object to this type variable, as far as I can tell. I can probably accomplish what I'm trying to do with mirrors, but I'd prefer not to if at all possible.
void example() {
Type myType = String;
String myExample = "Example";
//Syntax error here: The name 'myType' is not a type and cannot be used in an 'is' expression
if (myExample is myType) {
}
}
You can't generally test if a value is of a type using the Type object.
Type objects are reflected types, not real types. They represent the real type, but you can't use them in the code where you need a type: as type assertions, as generic type parameters or with the is/as operators. You must use the name of a type in those places, and not the name of a normal variable that happens to hold a Type object.
Clever stuff using mirrors might get there, but it's likely overkill for most cases (and I understand that you don't want it).
What you might be able to do instead, is to not pass around raw Type objects. You could instead make your own type abstraction, something like:
class MyType<T> {
const MyType();
Type get type => T;
bool isA(Object object) => object is T;
}
Then you can use that to represent types, not a Type object, and do something like:
void main(List<String> args) {
MyType myType = const MyType<String>();
String myExample = "Example";
if(myType.isA(myExample)) {
print('is');
} else {
print('is not');
}
}
That does require that your entire program uses your type objects to pass around types, but it also gives you a lot of control over those objects, so you can implement the functionality that you need.
I tried
library x;
void main(List<String> args) {
Type myType = String;
String myExample = "Example";
if(myExample.runtimeType == myType) {
print('is');
} else {
print('is not');
}
}
and it worked.
I have not much experience with such code in Dart though. Maybe that is not a fail-safe approach.
import 'package:reflection/reflection.dart';
void main() {
var childType = typeInfo(Child);
var baseType = typeInfo(Base);
if(childType.isA(baseType)) {
print("Child is Base");
}
if(baseType.isAssignableFrom(childType)) {
print("Base is assignable from Child");
}
}
class Base {
}
class Child extends Base {
}
Child is Base
Base is assignable for Child
P.S.
The "reflection" package incompatible with dart2js. It work only when used in Dart language.
How to cast Java.Lang.Object to some native type?
Example:
ListView adapter contains instances of native type Message. When i am trying to get SelectedItem from ListView it returns instance of Message type casted to Java.Lang.Object, but I can't find solution to cast Java.Lang.Object back to Message.
var message = (Message)list.SelectedItem;
// throws Error 5 Cannot convert type 'Java.Lang.Object' to 'Message'
Please Help.
After long time debuging, have found the solution:
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
Usage example:
var message = list.GetItemAtPosition(e.Position).Cast<Message>();
bundle.PutInt("Message", message.ID);
After careful sdk study have found MonoDroid integrated extension for this purpose:
public static TResult JavaCast<TResult>(this Android.Runtime.IJavaObject instance)
where TResult : class, Android.Runtime.IJavaObject
Member of Android.Runtime.Extensions
The least magical way of getting a native type from the Spinner is to call
message = ((ArrayAdapter<Message>)list.Adapter).GetItem(list.SelectedItemPosition);
I used this code from above answer and it works fine to me
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
and this is how I used
var selectedLocation = locationSpinner.SelectedItem.Cast<Location>();
I am able to get my location object fine from spinner
For generic collections, the right answer would be to use JavaList, which is a Java.Lang.Object and also implements IList. But it involves more work that's for sure. This is actually just an adapter for Java's ArrayList implementation.
You could always try the JavaCast<> method (most of the views implement this)(not tested):
var message = list.SelectedItem.JavaCast< Message >();
If for some reason GetChildAtPosition is not possible, serialise the object to json string and then deserialise the string back to native class.
All of the above answers are correct but I found the simplest way for my case was to make the object a subclass of Java.Lang.Object.
For example I'm writing a Android app in Monotouch, mimicking the concept of a UITableView in iOS using the ExpandableListAdapter, which requires the equivalent of UITableViewCells, so I subclassed cell objects from Java.Lang.Object allowing me to implement a subclass of ExpandableListAdapter such as
public override Java.Lang.Object GetChild(int position, int childPosition)
Etc.
it's work for me:
public class HolderHelper<T> : Java.Lang.Object {
public readonly T Value;
public HolderHelper (T value)
{
this.Value = value;
}
}
test:
chkFileName.Tag = new HolderHelper<LinkInfo> (item);
LinkInfo link= (chkFileName.Tag as HolderHelper<LinkInfo>).Value;