views:

434

answers:

7

Hi,

Is it possible to overload the default function operator (the () operator) in C#? If so - how? If not, is there a workaround to create a similar affect?

Thanks,
Asaf

EDIT:
I'm trying to give a class a default operator, something along the lines of:

class A {
    A(int myvalue) {/*save value*/}

    public static int operator() (A a) {return a.val;}
    ....
   }

...
A a = new A(5);
Console.Write(A());

EDIT 2:
I've read the spec and I understand there's no straight forward way to do this. I was hoping there's a workaround.

EDIT 3: The motivation is to make a class, or an instance behave like a function, to make a convenient logging interface. By the way, this is doable and reasonable in C++.

+5  A: 

No, () isn't an operator so it cannot be overloaded. (This is incorrect, please see Eric Lippert's comment below) The parentheses are part of C#'s syntax that are used to express a set of arguments that are passed to a method. () simply indicates that the method in question specified no formal parameters and therefore requires no arguments.

What are you trying to do? Perhaps if you gave a small example of the problem we would be able to help with a solution.

Edit: Okay I see what you are getting at now. You could always create a delegate that maps to the method on the instance like this (given that class A defines a method like this: public void Foo() { }):

Action action = someA.Foo;

Then you could invoke the delegate with a simple syntax like this:

action();

Unfortunately (or not, depending on your preference) this is pretty much as close as C# will let you get to this kind of syntax.

Andrew Hare
The function call operator most *certainly* is an operator. It is not an overloadable operator, but it absolutely is an operator; it has operands, it has operator precedence, it has associativity, it is documented as an operator, parsed as an operator and codegenned as an operator.
Eric Lippert
Thanks Eric - duly noted!
Andrew Hare
A: 

Asaf,

Why would you want to do that? What are you trying to accomplish?

AlexFreitas
I upvoted one of your questions to get you to the magical comment rep number. Feel free to move this to the comments of the question.
Austin Salonen
Hurry up and delete this before you drop below 50...
Austin Salonen
+7  A: 

There is not. Section 7.2.2 of the C# specification defines the overloadable operators as:

UNARY: + - ! ~ ++ -- true false
BINARY: + - * / % & | ^ << >> == != > <

= <=

Your readability would go to all hell anyway. Maybe there's another way to achieve what you're trying to do?

Chris B. Behrens
+1 For quoting the spec.
Andrew Hare
A: 

Why do you want to do this? Perhaps you're looking for the [] operator overload?

jrummell
A: 

You can't overload (), but you can take an object and make a delegate (similar to a function pointer) out of one of its methods:

class Foo
{ 
    private Bar bar;
    // etc.

    public Baz DoSomething(int n)
    {
        // do something, for instance, 
        // get a Baz somehow from the 'bar' field and your int 'n'
        // ...
    }
}

Now, DoSomething is a method that takes an int and returns a Baz, which is compatible with delegate type Func<int, Baz>.
(There's Action and Action<T> for methods that return void, and take, respectively, no or one argument. There's also Func<T1, T2, TResult> and variants for accepting more arguments.)

So you could have a method that takes a Func<int, Baz>, and does whatever with it:

void Frob(Func<int, Baz> f)
{
        Baz b = f(5); 
        // do whatever with your baz
}

Finally, creating the delegate and passing it to Frob goes like this:

Foo foo = new Foo();
Func<int, Baz> f = new Func<int, Baz>(foo.DoSomething);
Frob(f);

Does this help anything at all? I'm still pretty unclear on what exactly you want to accomplish.

Joren
A: 

You mention that you want to do logging, here is how you could do that with delegates:

FooBar MyAlgorithm(Foo paramA, Bar paramB, Actions<string> logger) {
    logger("Starting algorithm.")
    FooBar result = ...;
    logger("Finished algorithm.");
    return result;
}

When you run this you could log to the console:

MyAlgorithm(a, b, (text) => Console.WriteLine(text));

Or log to a Windows Forms TextBox:

TextBox logbox = form.GetLogTextBox();
MyAlgorithm(a, b, (text) => logbox.Text += text + Environment.NewLine);
Hallgrim
A: 

Check out implicit conversion. Another option would be explict conversion, but then you would need to cast the object type.

public class A
{
    public A(int myValue)
    {
        this.MyValue = myValue;
    }
    public int MyValue { get; private set; }

    public static implicit operator int(A a)
    {
        return a.MyValue;
    }
    public static implicit operator A(int value)
    {
        return new A(value);
    }
    // you would need to override .ToString() for Console.WriteLine to notice.
    public override string ToString()
    {
        return this.MyValue.ToString();
    }
}
class Program
{
    static void Main(string[] args)
    {
        A t = 5;
        int r = t;
        Console.WriteLine(t); // 5
    }
}
Matthew Whited