Can you automatically pass "this" as parameter? - c#

Is there an option to automatically pass this as parameter to a function? For example, you can use [CallerMemberName] to automatically pass string name. I'm looking for exact option with this.
Example:
void PassMeThis([AutomaticThisParam] object source);
and usage:
public class SomeClass{
void SomeMethod(){
PassMeThis(); // instead of PassMeThis(this)
}
}

Yes absolutely. This is called an extension Method.
Create a static class
Public static class MethodExtensions
Add a static method to it like this
public static PassMeThis(this SomeClass model) { // }
Call the method like this (referring to your code example):
this.PassMeThis()
And it's automaticly filled.
I hope thats what you were looking for

If PassMeThis is in the same class (or ancestor), as in your example, there is no point, this is avaiable there, too.
If it is in another class, there is no way to automatically get a reference to the calling object: IS there any way to get a reference to the calling object in c#?

Related

C# Access a static method that is hidden by a local property

I'm sure this must have been asked already, but I can't seem to find the answer. I need to know how to access a static method, when the class it is defined within has been hidden by an instance method with the same name.
I have a class which exposes a static method as follows:
public class Plan
{
public static Plan Generate(Project project)
{
var plan = new Plan();
// ...
return plan;
}
}
I then have another class which contains a method called "Plan", from which I want to call the static method mentioned above:
public ActionResult Plan(int id)
{
// ...
var plan = Plan.Generate(project);
// ...
}
The problem is that the class name 'Plan' is hidden by the method name, so I cannot call the static method directly.
Qualify your access to the Plan type with the type's name. For example:
YourNamespace.Plan.Generate
That said, static methods are bad mkay. Make yourself an IPlanFactory, bind PlanFactory to it and let dependency injection do the rest (assuming you're using constructor injection and not that hairbrained dependency resolver stuff). Now it's unambigiously _planFactory.Generate(...) and you've just increased testability. Give yourself a raise!

How to get the methodname from a known method?

Is it possible to get the name of another method in the same class but without using a manually written string?
class MyClass {
private void doThis()
{
// Wanted something like this
print(otherMethod.name.ToString());
}
private void otherMethod()
{
}
}
You may ask why: well the reason is that I must invoke the method later on like this Invoke("otherMethod"), however I don't want to hardcode this string myself as I can't refactor it anymore within the project.
One approach is you can wrap it into delegate Action, then you can access the name of method:
string name = new Action(otherMethod).Method.Name;
You can use reflection (example - http://www.csharp-examples.net/get-method-names/) to get the method names. You can then look for the method that you're looking for by name, parameters or even use an attribute to tag it.
But the real question is - are you sure this is what you need? This looks as if you don't really need reflection, but need to think over your design. If you already know what method you're going to invoke, why do you need the name? How about a using a delegate? Or exposing the method via an interface and storing a reference to some class implementing it?
Try this:
MethodInfo method = this.GetType().GetMethod("otherMethod");
object result = method.Invoke(this, new object[] { });
Btw. I also found (in the expansions of the internet) an alternative solution for only getting the string of a method. It also works with parameters and return types:
System.Func<float, string> sysFunc = this.MyFunction;
string s = sysFunc.Method.Name; // prints "MyFunction"
public string MyFunction(float number)
{
return "hello world";
}

c# cannot declare static and non static methods with same parameters?

If I try to declare static and non-static methods with the same parameters compiler returns an error: type 'Test' already defines a member called 'Load' with the same parameter types.
class Test
{
int i = 0;
public int I
{
get { return i; }
set { i = value; }
}
public bool Load(int newValue)
{
i = newValue;
return true;
}
public static Test Load(int newValue)
{
Test t = new Test();
t.I = newValue;
return t;
}
As far as I know these two methods can not be mixed, non static method is called on object whereas static method is called on class, so why does compiler not allow something like this and is there a way to do something similar?
If your Test class had a method like this:
public void CallLoad()
{
Load(5);
}
the compiler would not know which Load() to use. Calling a static method without the class name is entirely allowed for class members.
As for how to do something similar, I guess your best bet is to give the methods similar but different names, such as renaming the static method to LoadTest() or LoadItem().
Inside the class itself, you call both instance methods and static methods without an instance or the class name, thus making the two undistinguishable if the names and parameters are the same:
class Test
{
public void Foo()
{
Load(0); // Are you trying to call the static or the instance method?
}
// ...
}
The signature of a method is the combination of name and parameters (number and types).
In your case, your 2 methods have the same identical signature. The fact that one is static and other one is not makes no difference in accepting them as valid methods for the class.
I don't think so. if a non static method in this class calls Load(intValue). which method will be called?
Both methods have the same name, defined in the same class (scope) and with the same signature. C# does not allow this.
The problem is not related with writing this or the classname. C# specs allow you to call static methods using object instances:
AClass objectA = new AClass();
objectA.CallStaticMethod();
This code is valid so the compiler never has a way to know if you're calling a static or an instance method.
In C# a method cannot be overloaded by return type. It must at least have a different set of parameters, regardless if the method is static or not.

Calling a static method of class type C#

I am a newbie to asp.net and c#..I've been asked to analyse the code of a portal. Please look at the following code and suggest me a way to call the FromDatabase method. I've gone through all the files in the solution but there is no call statement to it.
Here Account and Utility are classes.
public static Account FromDatabase(DbDataRecord dr)
{
return new Account(
Utility.StringFromNull(dr.GetValue(0)),
Utility.StringFromNull(dr.GetValue(1)),
Utility.IntFromNull(dr.GetValue(2)),
Utility.StringFromNull(dr.GetValue(3)),
Utility.StringFromNull(dr.GetValue(4)),
Utility.StringFromNull(dr.GetValue(5)),
Utility.DateTimeFromNull(dr.GetValue(6))
);
}
In what other way can I return the values instead of return new Account().
Thanks in advance!
To use a static method you just use the class, and not an instance of it. I.E.: say your method is in class MyClass, then you just do
MyClass.FromDataBase(yourDataRow);
You can call a static method by using the class name that the static method belongs to...
Example:
public class MyClass {
public static object MyMethod() {}
}
To call it:
MyClass.MyMethod();
Account myAccount = Account.FromDatabase(dr);
call it this way:
NameOfStaticClass.FromDatabase(dbRec)
and NameOfStaticClass is the name of class in witch FromDatabase method is declared
You can call the Account.FromDatabase method by using the typeName of the class it lives in (I assumy it is a method on the Account class itself. However it will always result a Account object.
You can create another method that will parse the DbDataRecord object and return it in any collection object, for example an array.

Can I use some other class's function as a delegate?

Say I have 2 classes, class A and class B. Class A creates an instance of Class B. Class A has a function that I would like to pass into a method from Class B.
class A {
void Main(string[] args) {
B classB=new B();
DelegateCaller(new delFunction(classB.TheFunction()); // <-- Won't compile (method name expected)
DelegateCaller(new delFunction(B.TheFunction()); // <-- Won't compile (object reference is req'd)
}
public delegate string delFunction();
public DelegateCaller(delFunction func) {
System.Console.WriteLine(func());
}
}
class B {
public string TheFunction() {
return "I'm Printing!!!";
}
}
I'm not sure if it a syntax issue or it's just something I can't do. Maybe I need to define the delegate in B, but reference it in A? What about B's this pointer?
It's just a syntax issue; get rid of the parentheses after classB.TheFunction - they indicate that you wish to invoke the method.
DelegateCaller(new delFunction(classB.TheFunction));
Do note that there is an implicit conversion available from a method-group, so you can just do:
DelegateCaller(classB.TheFunction);
Also note that creating your own delegate-type in this case is unnecessary; you could just use the in-built Func<string> type.
EDIT: As Darin Dimitrov points out, there is also the unrelated issue of calling an instance method as though it were a static method.
Try like this:
class A
{
static void Main()
{
B classB = new B();
DelegateCaller(classB.TheFunction);
}
public delegate string delFunction();
public static void DelegateCaller(delFunction func)
{
Console.WriteLine(func());
}
}
class B
{
public string TheFunction()
{
return "I'm Printing!!!";
}
}
Let me elaborate about the different changes I've made to your initial code:
TheFunction in class B needs to be public so that you can access it from class A
The DelegateCaller method in class A should be static and not necessarily return a value (declare it as void) if you want to call it from the static Main method.
The definition of the delFunction delegate should return a string.
Take the parenthesis off the end of TheFunction. You want the method, not the result of a call to the method.
If you want to capture an instance method for usage in a general purpose fashion you should use Delegate.CreateDelegate(Type,MethodInfo). This is nice as it allows you to create an "open delegate" meaning it isn't bound to an instance and can take any instance that is a ClassB. It makes reflection quite fast if you know the type information, as this method will perform much faster than the equivalent statement using MethodInfo.Invoke.
DelegateCaller(new delFunction(B.TheFunction());
Should be
DelegateCaller(new delFunction(B.TheFunction);
To use classB.TheFunction you would need to make TheFunction static. You pass in the function with no parens.

Categories

Resources