Is it by any chance possible to call a method without referencing to its class?
For instance, you have a helper class:
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
And then you need to call it:
class MainClass
{
public static void Main()
{
HelperTools.DoWork();
}
}
Is it possible to call DoWork(); without a reference? Like this:
public static void Main()
{
DoWork();
}
Just for sake of simplicity.
Not quite, but here are 5 patterns that get you close:
namespace My.Namespace
{
using H = MyHelperClass;
public class MyHelperClass
{
public static void HelperFunc1()
{
Console.WriteLine("Here's your help!");
}
}
public class MyHelperClass2
{
public static void HelperFunc4()
{
Console.WriteLine("Here's your help!");
}
}
public interface IHelper{ }
public static class HelperExtensions
{
public static void HelperFunc3(this IHelper self)
{
Console.WriteLine("Here's your help!");
}
}
public class MyClass : MyHelperClass2, IHelper
{
private static readonly Action HelperFunc2 = MyHelperClass.HelperFunc1;
private static void HelperFunc5()
{
Console.WriteLine("Here's your help!");
}
public void MyFunction()
{
//Method 1 use an alias to make your helper class name shorter
H.HelperFunc1();
//Method 2 use a class property
HelperFunc2();
//Method 3 extend an interface that has extension methods.
//Note: you'll have to use the this keyword when calling extension
this.HelperFunc3();
//Method 4 you have access to methods on classes that you extend.
HelperFunc4();
//Method 5 put the helper method in your class
HelperFunc5();
}
}
}
No. Java has the concept of importing static like this, but C# does not. (IMO, a naked DoWork() without any clue as to where the implementation resides is non-ideal.)
a few years late but maybe this will help someone else...
Use a using static directive to reference the static class: (introduced in C# 6)
using static HelperTools;
class MainClass
{
public static void Main()
{
DoWork();
}
}
---------------- HelperTools.cs--------------------
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
The only place you can call DoWork from without referencing the class name is within the class itself. For instance, if you add a non-static method to HelperTools:
public void foo()
{
DoWork();
}
You can call DoWork from within it, even though foo() is not static.
Related
suppose I have this class:
Class Foo:
method1(){}
method2(){}
method3(){}
...
And suppose I have some action I wanted to do repeatedly in several methods in the class. Each action will take before the methods occur and after it occur. Is there an elegant way to implement it? The only way came to my mind:
private void Setup(Action action)
{
//Do something before
action
//Do something after
}
private void method1(args)
{
Setup(()=>method)
}
But it will make me call repeatedly call for Setup in each function I would like to implement it.
I have made a quick exemple with DispatchProxy
Inspiration : DispatchProxy
https://dotnetfiddle.net/GzDR9r
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
//https://www.c-sharpcorner.com/article/aspect-oriented-programming-in-c-sharp-using-dispatchproxy/
public class Program
{
public static void Main()
{
var foo = new Foo();
var decoratedFoo = AspectDecorator<IFoo>.Create(foo);
Console.WriteLine("\n\nClass:\n");
foo.method1();
foo.method2();
foo.method3();
Console.WriteLine("\n\nDecorated Class:\n");
decoratedFoo.method1();
decoratedFoo.method2();
decoratedFoo.method3();
}
}
public class Foo : IFoo{
public void method1(){Console.WriteLine("> call method1");}
public void method2(){Console.WriteLine("> call method2");}
public void method3(){Console.WriteLine("> call method3");}
}
public interface IFoo{
void method1();
void method2();
void method3();
}
public class AspectDecorator<T> : DispatchProxy
{
private T _impl;
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
Console.WriteLine($"Before : {targetMethod.Name}");
var obj = _impl.GetType().GetMethod(targetMethod.Name).Invoke(_impl, args);
Console.WriteLine($"After : {targetMethod.Name}");
return obj;
}
public void SetTarget(T target)
{
this._impl = target;
}
public static T Create(T decorated)
{
object proxy = Create<T, AspectDecorator<T>>();
((AspectDecorator<T>) proxy)._impl=decorated;
return (T)proxy;
}
}
I find that in some cases, there is a lot of code in a constructor, or a class has two or more constructors which have comparable code. In these cases, I often create a private method. In the former case to improve readability, in the latter to prevent duplicate code.
In some of these cases this results in a private method that should ONLY be called from the constructor (for whatever reason). Is there a way to enforce this? I could imagine doing something like this:
using System.Diagnostics;
public class Foo
{
private bool _constructing = true;
private Foo()
{
_constructing = false;
}
public Foo(string someString) : this()
{
// constructor-specific code
Initialize();
}
public Foo(double someDouble) : this()
{
// constructor-specific code
Initialize();
}
private void Initialize()
{
Debug.Assert(!_constructing, "Initialize method should only be called from constructor");
// shared code
}
}
but this feels somewhat clunky. Does anyone have a better suggestion?
Edit: added constructor chaining to example; I meant for this to be in the original example.
Edit: I think I missed a point in my original question - while chaining constructors does provide a solution in some cases, the chained code is always executed prior to the code in the constructor that you're chaining from (which, incidentally, is why the above example doesn't work). There are cases where you want to execute some part of shared code, and then do something else. I'll add another example to reflect this:
using System.Diagnostics;
public class Foo
{
private bool _constructing = true;
public Foo(string someString)
{
// constructor-specific pre-processing code
Initialize();
// constructor-specific post-processing code
_constructing = false;
}
public Foo(double someDouble)
{
// constructor-specific pre-processing code
Initialize();
// constructor-specific post-processing code
_constructing = false;
}
private void Initialize()
{
Debug.Assert(!_constructing, "Initialize method should only be called from constructor");
// shared code
}
}
Constructors can call each other:
class Foo
{
private Foo()
{
}
public Foo(int value) : this()
{
}
}
I think, you could use this feature.
You can use the CallerMemberName for that. The compiler will fill that with the original method the method is called from. In this case .ctor (constructor):
public static class Program
{
static void Main(string[] args)
{
A a = new A();
}
}
class A
{
public A()
{
B();
}
[MethodImplOptions.NoInlining]
private void B([CallerMemberName] string caller = null)
{
if (caller == ".ctor")
{
}
}
}
To prevent inlining, you can put the MethodImplOptions.NoInlining on the method B.
I suggest that you do this:
public class Foo
{
private Foo()
{
// private constructors can only be called from
// within the class during constuction
}
public Foo(string someString) : this()
{
}
public Foo(double someDouble) : this()
{
}
}
The use of : this() can only be called during construction and while this doesn't force your public constructors calling : this() you don't have any such guarantee that your public constructors will call Initialize() anyway.
How can I add a method from class A to a delegate of class B without knowing in advance which method I will be adding and what class A is? And then call that delegate from class A?
class Class {
public string someProperty;
public delegate void myDelegate(Class obj);
myDelegate handler = new myDelegate(mainClassMethod); //here is the problem..
public void someMethod() {
handler();
}
}
class MainClass {
public static void Main() {
Class classObj = new Class();
classObj.someProperty = "hello";
public void mainClassMethod(Class obj) {
System.Console.WriteLine(obj.someProperty);
}
classObj.someMethod();
}
}
Should I use something other than delegates for this? By the way I am doing this in C#!
make mainClassMethod static and access it via class name MainClass. Also you cant declare nested functions as class members, you need to declare mainClassMethod separately.
class MainClass {
public static void Main()
{
Class classObj = new Class();
classObj.someProperty = "hello";
classObj.someMethod();
}
public static void mainClassMethod(Class obj)
{
System.Console.WriteLine(obj.someProperty);
}
}
Also you declared delegate void myDelegate(Class obj); so you need to pass instance of a Class as a parameter. In my example I pass object found by this reference, which is an object that you call someMethod at.
Now you can write:
class Class {
public string someProperty;
public delegate void myDelegate(Class obj);
myDelegate handler = new myDelegate(MainClass.mainClassMethod); //no error
public void someMethod()
{
handler(this);
}
}
I think I couldnt do this thing, but I try to ask (maybe :)).
Suppose I have this Main class :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
}
}
now if I want to try to call this instance from another Context Class (web application), I do this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(UiUtils.myObject.Title());
}
}
but what I'd like to do is this :
public partial class context_eventi_CustomClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
so, use directly myObject and not UiUtils.myObject :)
I think this is not possible, but maybe I wrong and there are any strategies :) Thanks
** EDIT **
my solution for the moment :
public class UiUtils
{
public static MyObject myObject;
public UiUtils()
{
myObject=new MyObject();
iContext.myObject = myObject;
}
}
public class iContext : System.Web.UI.UserControl
{
public static MyObject myObject;
public iContext()
{
}
public iContext(MyObject myObject)
{
myObject = myObject;
}
}
public partial class context_eventi_CustomClass : iContext
{
protected void Page_Load(object sender, EventArgs e)
{
Console.Write(myObject.Title());
}
}
seems to works! What do you think about?
Per MSDN,
A static method, field, property, or
event is callable on a class even when
no instance of the class has been
created. If any instances of the class
are created, they cannot be used to
access the static member. Only one
copy of static fields and events
exists, and static methods and
properties can only access static
fields and static events. Static
members are often used to represent
data or calculations that do not
change in response to object state.
and
"To access a static class member, use the name of the class instead of a variable name to specify the location of the member."
and
The static member is always accessed
by the class name, not the
instance name
#Daniel Earwicker says in his answer on SO here:
...Static members fail to integrate
well with inheritance. It makes no
sense to have them heritable. So I
keep static things in separate static
classes...
So I am not clear on your design why MyObject needs to be static. All you are trying to save is a little typing, but inheritance will not help you here either.
Edit:
I tried to replicate your code in a simple console application. The output is not what you would expect:
namespace ConsoleApplication1
{
public class UiUtils
{
public static int myObject = 1;
public UiUtils()
{
myObject = new int();
iContext.myObject = myObject;
Console.WriteLine("This is UiUtils\n");
}
}
public class iContext
{
public static int myObject = 2;
public iContext()
{
Console.WriteLine("This is iContext\n");
}
public iContext(int myObject)
{
myObject = myObject;
}
}
public class iContext2 : iContext
{
public static int myObject = 3;
public iContext2()
{
Console.WriteLine(myObject.ToString() + "\nThis is iContext2\n");
Console.WriteLine(iContext.myObject.ToString());
}
}
class Program
{
static void Main(string[] args)
{
iContext2 icontext = new iContext2();
Console.In.ReadLine();
}
}
}
The output ends up being this:
This is iContext
3
This is iContext2
If you add a call to iContext.myObject, then it outputs it's number:
This is iContext
3
This is iContext2
2
To access the object without typing the class you can use inheritance.
public class CustomClass : UiUtils
This will share UiUtils properties with CustomClass
I want to create a class that can only be inherited, for that i know it should be made abstract. But now the problem is that i want to use functions of that class without making them static. How can i do that.
public abstract Class A
{
A()
{}
public void display()
{}
}
public Class B:A
{
base.A() // this is accessible
this.display() // this is not accessible if i dont make this function static above
}
Your example will not compile, you could consider something like this:
using System;
public abstract class A
{
protected A()
{
Console.WriteLine("Constructor A() called");
}
public void Display()
{
Console.WriteLine("A.Display() called");
}
}
public class B:A
{
public void UseDisplay()
{
Display();
}
}
public class Program
{
static void Main()
{
B b = new B();
b.UseDisplay();
Console.ReadLine();
}
}
Output:
Constructor A() called
A.Display() called
Note: Creating a new B() implicitly calls A(); I had to make the constructor of A protected to prevent this error:
"'A.A()' is inaccessible due to its protection level"
That's not true. You don't have to make Display() static; you can call it freely from the subclass. On the other hand, you can't call the constructor like that.
Maybe it's just an error in the example, but the real issue with the code you have is that you can't put method calls in the middle of your class definition.
Try this:
public abstract class A
{
public void Display(){}
}
public class B:A
{
public void SomethingThatCallsDisplay()
{
Display();
}
}
Here's how you can do this..
public abstract class A
{
public virtual void display() { }
}
public class B : A
{
public override void display()
{
base.display();
}
public void someothermethod()
{
this.display();
}
}