I a sample C# console application to display a bug I am experiencing:
class Program
{
public enum Days { Sat = 1, Sun, Mon, Tue, Wed, Thu, Fri };
static void Main(string[] args)
{
AddWhere("a", DateTime.Now);
AddWhere("a", 0);
AddWhere("a", 2);
AddWhere("a", 3);
AddWhere("a", "4");
AddWhere("a", Days.Sun);
AddWhere("a", Days.Fri);
AddWhere("a", 1);
AddWhere("a", (int)Days.Sat);
Console.Read();
}
public static void AddWhere(string columnName, Days cd)
{
Console.WriteLine("enum fired");
}
public static void AddWhere(string columnName, object Val)
{
Console.WriteLine("object fired");
}
}
the output I get is this:
object fired
enum fired
object fired
object fired
object fired
enum fired
enum fired
object fired
object fired
Why does the enum method fire when 0 is passed in?
The special case of 0 is covered in section 1.10 of the C# language specification.
In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type
This implicit conversion is causing overload resolution to pick the enum overload over the object one.
JaredPar answered the question. I will add that the work-around is to cast the 0 as the exact type of the desired method overload.
AddWhere("a", (object)0);
Because enums are stored by default as integers and when the compiler tries to resolve the best method overload it decides that AddWhere(string columnName, Days cd) is a better match.
Enum fired because 0 is an int and the enum underlying type is int. 0 is implicitly converted to enum (at compile time) as this conversion is defined by the language.
int a = 123;
long b = a; // implicit conversion from int to long
int c = (int) b; // explicit conversion from long to int
Some conversions are defined by the language
Source: msdn.microsoft.com
Related
I am trying to build a class that stores a user-defined function inside of it for later use. I have decided to use the boost::function object to do so.
However, I get the following error on compile:
error: no match for ‘operator=’ in ‘((SomeClass*)this)->SomeClass::someFunction = ((SomeClass*)this)->SomeClass::DefaultFunction’
I do not understand this error, since someFunction and DefaultFunction should, as far as I can see, have the same types.
The code is shown below:
#include <boost/function.hpp>
class SomeClass{
private:
boost::function<int(int)> someFunction;
int DefaultFunction(int i);
public:
SomeClass();
~SomeClass();
void SetFunction(int (*f)(int));
};
int SomeClass::DefaultFunction(int i){
return i+1;
}
SomeClass::SomeClass(){
someFunction=DefaultFunction;
}
~SomeClass::SomeClass(){
}
void SomeClass::SetFunction(int (*f)(int i)){
someFunction=f;
}
void MyProgram(){
SomeClass s;
}
Can anyone offer any pointers as to how to construct such an object? Alternatively, iff there is a better way than the one I am attempting, could you explain it to me?
Kindest regards!
DefaultFunction is a member function of SomeClass.
Member function is called for some instance of SomeClass.
This function takes "hidden" pointer to SomeClass instance as its first parameter addition to int.
So member function is not the same as free function.
Your someFunction is object of boost::function, so it is wrapper for callable object.
Your requirements to that object are: take int and returns int.
In order to assign DefaultFunction (as member function) to someFunction you need to create this callable object.
Here you need to specify for which instance of SomeClass this object will be called, to do that use boost::bind:
SomeClass::SomeClass(){
someFunction=boost::bind(&SomeClass::DefaultFunction, this, boost::placeholders::_1);
}
In the code above you create callable object which will behave as
struct unnamedClass {
SomeClass* sc;
unnamedClass (SomeClass* sc) : sc(sc) {} // here sc is this of SomeClass
int operator()(int arg)
{
return sc->DefaultFunction(arg);
}
};
so when you invoke someFunction(10) it takes 10 as argument and call DefaultFunction for current this instance.
This
void SomeClass::SetFunction(int (*f)(int i)){
someFunction=f;
}
works because f is free function, which takes no hidden - pointer to class instance.
Using the answer of #rafix07, the following code compiled:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
class SomeClass{
private:
public:
SomeClass();
~SomeClass();
boost::function<int(int)> someFunction;
int DefaultFunction(int i);
void SetFunction(int (*f)(int));
};
int SomeClass::DefaultFunction(int i){
return i+1;
}
SomeClass::SomeClass(){
someFunction=boost::bind(&SomeClass::DefaultFunction, this, _1);
}
SomeClass::~SomeClass(){
}
void SomeClass::SetFunction(int (*f)(int i)){
someFunction=f;
}
int MyOwnProgram(int i){
return i+2;
}
void MyProgram(){
SomeClass s;
std::cout<<s.someFunction(2)<<std::endl;
s.SetFunction(MyOwnProgram);
std::cout<<s.someFunction(2)<<std::endl;
}
int main()
{
MyProgram();
}
The output from the program is:
3
4
I struggled to find a proper title for this question because the phenomenon I observed is very strange. Hence I skip explaining my problem literally and instead show you some (hopefully) self-describing code. Consider the following parameterized class:
public class GenericOptional<T> {
public GenericOptional(T someValue) {}
public T getValue() { return null; }
public Optional<String> getOptionalString() { return Optional.empty(); }
}
What I like to emphasize is that the return type Optional<String> of the method getOptionalString() does not depend on the type-parameter T.
Now have a look at the following code, which gets compiled inside Eclipse Luna 4.4.2 using Java 8u45:
public static void main(String[] args) {
Object obj = new GenericOptional<>(Boolean.TRUE);
GenericOptional go = (GenericOptional) obj;
Optional os = go.getOptionalString();
}
The local variable os has the type Optional without the type-parameter String! The Eclipse compiler has lost the information about the fixed type-parameter. Does anyone know why?
Now look at a second code example:
public static void main(String[] args) {
Object obj = new GenericOptional<>(Boolean.TRUE);
GenericOptional<?> go = (GenericOptional) obj;
Optional<String> os = go.getOptionalString();
}
By declaring the local variable go as GenericOptional<?> the return type of the method getOptionalString() now is Optional<String> as expected.
May anyone explain this behavior?
You are facing the behavior of raw types. When you are using a raw type, Generics are effectively turned off completely, regardless of whether there is a connection between the generic signature of the member and the type parameter of the class.
The reasoning behind this is that raw types are a feature for backward compatibility with pre-Generics code only. So either you have Generics or your don’t.
If the Generic method does not depend on the actual type parameter of the class, the problem is easy to fix:
GenericOptional<?> go = (GenericOptional<?>) obj;
Optional<String> os = go.getOptionalString();
Using <?> implies “I don’t know the actual type parameter and I don’t care but I’m using Generic type checking”.
It's not about Eclipse or anything, but about raw types.
Let's review this snippet:
public static void main(String[] args) {
Object obj = new GenericOptional<>(Boolean.TRUE);
GenericOptional go = (GenericOptional) obj;
Optional os = go.getOptionalString();
}
Here, you're creating a raw instance of GenericOptional, which means that the type-parameter information will be completely turned off. So, instantiating a raw GenericOptional means that the instance will expose the methods as following:
public class GenericOptional {
public GenericOptional(Object someValue) {}
public Object getValue() { return null; }
public Optional getOptionalString() { return Optional.empty(); }
}
However, if we now review the second snippet
public static void main(String[] args) {
Object obj = new GenericOptional<>(Boolean.TRUE);
GenericOptional<?> go = (GenericOptional) obj;
Optional<String> os = go.getOptionalString();
}
we can see that you're making a generic instance of GenericOptional. Even it's type-parameter is <?>, the compiler will not turn-off caring about type-parameters, so the instance will expose the getOptionalString() method parameterized, like this:
public Optional<String> getOptionalString() { return Optional.empty(); }
Can a method present in the RequestContext method return void?
If my RequestContext looks like this,
#Service( value = PersonUtil.class, locator = PersonLocator.class )
public interface PersonRequest extends RequestContext
{
Request<void> testMethod( Long id );
......
}
I am getting this error:
Multiple markers at this line
- Return type for the method is missing
- Syntax error on token "void", Dimensions expected after
Can we not create a method with return type void? If not, why is it so?
Thanks in advance.
void is just like primitive types like int or boolean, you can't use it as a type parameter.
And just like you'd use Integer instead of int, you'll use Void here (java.lang.Void)
I have read the description, and I understand that it is a function-type alias.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.yyd520hand9j
But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
I think I need one or two real code examples.
A common usage pattern of typedef in Dart is defining a callback interface. For example:
typedef void LoggerOutputFunction(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Running the above sample yields the following output:
Hello World
2012-09-22 10:19:15.139: Hello World
The typedef line says that LoggerOutputFunction takes a String parameter and returns void.
timestampLoggerOutputFunction matches that definition and thus can be assigned to the out field.
Let me know if you need another example.
Dart 1.24 introduces a new typedef syntax to also support generic functions. The previous syntax is still supported.
typedef F = List<T> Function<T>(T);
For more details see https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generic-function-type-alias.md
Function types can also be specified inline
void foo<T, S>(T Function(int, S) aFunction) {...}
See also https://www.dartlang.org/guides/language/language-tour#typedefs
typedef LoggerOutputFunction = void Function(String msg);
this looks much more clear than previous version
Just slightly modified answer, according to the latest typedef syntax, The example could be updated to:
typedef LoggerOutputFunction = void Function(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Typedef in Dart is used to create a user-defined function (alias) for other application functions,
Syntax: typedef function_name (parameters);
With the help of a typedef, we can also assign a variable to a function.
Syntax:typedef variable_name = function_name;
After assigning the variable, if we have to invoke it then we go as:
Syntax: variable_name(parameters);
Example:
// Defining alias name
typedef MainFunction(int a, int b);
functionOne(int a, int b) {
print("This is FunctionOne");
print("$a and $b are lucky numbers !!");
}
functionTwo(int a, int b) {
print("This is FunctionTwo");
print("$a + $b is equal to ${a + b}.");
}
// Main Function
void main() {
// use alias
MainFunction number = functionOne;
number(1, 2);
number = functionTwo;
// Calling number
number(3, 4);
}
Output:
This is FunctionOne
1 and 2 are lucky numbers !!
This is FunctionTwo
3 + 4 is equal to 7
Since dart version 2.13 you can use typedef not only with functions but with every object you want.
Eg this code is now perfectly valid:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
For more details see updated info:
https://dart.dev/guides/language/language-tour#typedefs
https://www.tutorialspoint.com/dart_programming/dart_programming_typedef.htm
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}
I am new to C# 3.0 var type. Here I have a question about this type. Take the following simple codes in a library as example:
public class MyClass {
public var Fn(var inValue)
{
if ( inValue < 0 )
{
return 1.0;
}
else
{
return inValue;
}
}
}
I think the parameter is an anonymous type. If I pass in a float value, then the Fn should return a float type. If a double value type is passed in, will the Fn return a double type? How about an integer value type as input value?
Actually, I would like to use var type with this function/method to get different return types with various input types dynamically. I am not sure if this usage is correct or not?
You can't use var for return values or parameter types (or fields). You can only use it for local variables.
Eric Lippert has a blog post about why you can't use it for fields. I'm not sure if there's a similar one for return values and parameter types. Parameter types certainly doesn't make much sense - where could the compiler infer the type from? Just what methods you try to call on the parameters? (Actually that's pretty much what F# does, but C# is more conservative.)
Don't forget that var is strictly static typing - it's just a way of getting the compiler to infer the static type for you. It's still just a single type, exactly as if you'd typed the name into the code. (Except of course with anonymous types you can't do that, which is one motivation for the feature.)
EDIT: For more details on var, you can download chapter 8 of C# in Depth for free at Manning's site - this includes the section on var. Obviously I hope you'll then want to buy the book, but there's no pressure :)
EDIT: To address your actual aim, you can very nearly implement all of this with a generic method:
public class MyClass
{
public T Fn<T>(T inValue) where T : struct
{
Comparer<T> comparer = Comparer<T>.Default;
T zero = default(T);
if (comparer.Compare(inValue, zero) < 0)
{
// This is the tricky bit.
return 1.0;
}
else
{
return inValue;
}
}
}
As shown in the listing, the tricky bit is working out what "1" means for an arbitrary type. You could hard code a set of values, but it's a bit ugly:
public class MyClass
{
private static readonly Dictionary<Type, object> OneValues
= new Dictionary<Type, object>
{
{ typeof(int), 1 },
{ typeof(long), 1L },
{ typeof(double), 1.0d },
{ typeof(float), 1.0f },
{ typeof(decimal), 1m },
};
public static T Fn<T>(T inValue) where T : struct
{
Comparer<T> comparer = Comparer<T>.Default;
T zero = default(T);
if (comparer.Compare(inValue, zero) < 0)
{
object one;
if (!OneValues.TryGetValue(typeof(T), out one))
{
// Not sure of the best exception to use here
throw new ArgumentException
("Unable to find appropriate 'one' value");
}
return (T) one;
}
else
{
return inValue;
}
}
}
Icky - but it'll work. Then you can write:
double x = MyClass.Fn(3.5d);
float y = MyClass.Fn(3.5f);
int z = MyClass.Fn(2);
etc
You cannot use var as a return type for a method.