public vs public static Methods - c#

Having read the access modifiers in C# progamming tutorial, I come to conclusion that defining a method public is enough for it to be "seen" from another Form of the same namespace.
However, in practise whenever I tried to implement this, I also had to define the method as static in order for it to be referenced from other Forms of the same namespace.
Am I loosing something?
I am doing somethning wrong?

For a public static method, you don't need a reference to an object. The method is static and can be accessed on class level.
If you can't access a public method, then you need a reference to the object, then you can.
public class AClass
{
public void DoSomething() {}
public static void DoSomethingElse() {}
}
You can use them as follows:
AClass.DoSomethingElse(); // no object reference required
AClass.DoSomething(); // will give compiler error, since you have no object reference.
var anObject = new AClass();
anObject.DoSomething(); // will work fine.
anObject.DoSomethingElse(); // compile error (thx hvd).

public static method do not need object instance, they can be used without creating any instance of the class
ClassName.MyStaticPublicMethodName()
where as public (non-static) method require an Instance of the Class, public (non-static) method in general helps you to work with the data member (field) of the object.
To use a non-static public method you need to create instance of the class
ClassName obj = new ClassName();
obj.MyPublicMethod();

Related

Can we create more than 1 instance using Private Constructor?

We all know that we cannot create object of class having private constructor. So the question arises is how many instances of this class can be created .Please find a sample code below.
public class Test
{
public int val ;
private Test(int sent)
{
val=val +sent;
}
public static void Callme(int GetVal)
{
Test obj=new Test(GetVal);
Console.WriteLine(obj.val);
}
}
public class Program
{
public static void Main()
{
Test.Callme(10);
//Console.WriteLine(Test.val);
Test.Callme(20);
//Console.WriteLine(Test.val);
}
}
As per what I know It should create 2 object of the class. Need help understanding this.
We all know that we cannot create object of class having private constructor.
Well, that's not accurate. You can create an object (instance) of a class having only private constructors by using static members of that class, just like in the code in the question.
What you can't do is create an instances of that class from anywhere else in the code.
how many instances of this class can be created
In your code sample there are two instances of class Test.
I think what might be confusing you is you expected the second Console.WriteLine to print 30, but it printed 20. That is because public int val ; is an instance member. If it was a static member, than it would have printed 30
Maybe something like this is what you're looking for:
public static Test Callme(int GetVal)
{
Test obj = new Test(GetVal);
Console.WriteLine(obj.val);
return obj;
}
And then create new instances like:
Test test1 = Test.Callme(10);
Test test2 = Test.Callme(20);
This way you can easily access the members of each instance. E.g. test1.val
Callme method is a static method. Static methods does not require an objects instance to be called upon. They don't have the this (keyword) reference and can be called directly on the class. In your situation Test.CallMe(someValue). Note that there is no object instance involved here.
If CallMe was NOT a static method you would have needed an instance/object to call it. For example
Test ob = new Test();
ob.CallMe(someValue);
What your example illustrates is the use of private fields/methods.
When a method like the constructor or a filed is marked with the private keyword that method/field can only be called/accessed from within the declaring class.
This means that CallMe can access the constructor because CallMe is a member of the class and the constructor is a member of the class thus they both can access each other.
When a class has only one constructor and that constructor is private it effectively means that an instance of the class can only be created from within the class.
So in current example CallMe creates an instance of the class each time it's called.
If you call CallMe 2 times you'll create 2 instances of the class.
Because the method Callme is static it is instantiated by the system at some point before it is used and then remains in memory for future calls. There is only one copy of a static memeber of a class ever created regardless of how many instances of the class are created.

Get name of property static as a string [duplicate]

I am getting into C# and I am having this issue:
namespace MyDataLayer
{
namespace Section1
{
public class MyClass
{
public class MyItem
{
public static string Property1{ get; set; }
}
public static MyItem GetItem()
{
MyItem theItem = new MyItem();
theItem.Property1 = "MyValue";
return theItem;
}
}
}
}
I have this code on a UserControl:
using MyDataLayer.Section1;
public class MyClass
{
protected void MyMethod
{
MyClass.MyItem oItem = new MyClass.MyItem();
oItem = MyClass.GetItem();
someLiteral.Text = oItem.Property1;
}
}
Everything works fine, except when I go to access Property1. The intellisense only gives me "Equals, GetHashCode, GetType, and ToString" as options. When I mouse over the oItem.Property1, Visual Studio gives me this explanation:
MemberMyDataLayer.Section1.MyClass.MyItem.Property1.getcannot be accessed with an instance reference, qualify it with a type name instead
I am unsure of what this means, I did some googling but wasn't able to figure it out.
In C#, unlike VB.NET and Java, you can't access static members with instance syntax. You should do:
MyClass.MyItem.Property1
to refer to that property or remove the static modifier from Property1 (which is what you probably want to do). For a conceptual idea about what static is, see my other answer.
You can only access static members using the name of the type.
Therefore, you need to either write,
MyClass.MyItem.Property1
Or (this is probably what you need to do) make Property1 an instance property by removing the static keyword from its definition.
Static properties are shared between all instances of their class, so that they only have one value. The way it's defined now, there is no point in making any instances of your MyItem class.
I had the same issue - although a few years later, some may find a few pointers helpful:
Do not use ‘static’ gratuitously!
Understand what ‘static’ implies in terms of both run-time and compile time semantics (behavior) and syntax.
A static entity will be automatically constructed some time before
its first use.
A static entity has one storage location allocated, and that is
shared by all who access that entity.
A static entity can only be accessed through its type name, not
through an instance of that type.
A static method does not have an implicit ‘this’ argument, as does an
instance method. (And therefore a static method has less execution
overhead – one reason to use them.)
Think about thread safety when using static entities.
Some details on static in MSDN:
Static Classes in C#
Static Constructors in C#
This causes the error:
MyClass aCoolObj = new MyClass();
aCoolObj.MyCoolStaticMethod();
This is the fix:
MyClass.MyCoolStaticMethod();
Explanation:
You can't call a static method from an instance of an object. The whole point of static methods is to not be tied to instances of objects, but instead to persist through all instances of that object, and/or to be used without any instances of the object.
No need to use static in this case as thoroughly explained. You might as well initialise your property without GetItem() method, example of both below:
namespace MyNamespace
{
using System;
public class MyType
{
public string MyProperty { get; set; } = new string();
public static string MyStatic { get; set; } = "I'm static";
}
}
Consuming:
using MyType;
public class Somewhere
{
public void Consuming(){
// through instance of your type
var myObject = new MyType();
var alpha = myObject.MyProperty;
// through your type
var beta = MyType.MyStatic;
}
}
cannot be accessed with an instance reference
It means you're calling a STATIC method and passing it an instance. The easiest solution is to remove Static, eg:
public static void ExportToExcel(IEnumerable data, string sheetName)
{
Remove the static in the function you are trying to call. This fixed the problem for me.
I got here googling for C# compiler error CS0176, through (duplicate) question Static member instance reference issue.
In my case, the error happened because I had a static method and an extension method with the same name. For that, see Static method and extension method with same name.
[May be this should have been a comment. Sorry that I don't have enough reputation yet.]
I know this is an old thread, but I just spent 3 hours trying to figure out what my issue was. I ordinarily know what this error means, but you can run into this in a more subtle way as well. My issue was my client class (the one calling a static method from an instance class) had a property of a different type but named the same as the static method. The error reported by the compiler was the same as reported here, but the issue was basically name collision.
For anyone else getting this error and none of the above helps, try fully qualifying your instance class with the namespace name. ..() so the compiler can see the exact name you mean.
Check whether your code contains a namespace which the right most part matches your static class name.
Given the a static Bar class, defined on namespace Foo, implementing a method Jump or a property, chances are you are receiving compiler error because there is also another namespace ending on Bar. Yep, fishi stuff ;-)
If that's so, it means your using a Using Bar; and a Bar.Jump() call, therefore one of the following solutions should fit your needs:
Fully qualify static class name with according namepace, which result on Foo.Bar.Jump() declaration. You will also need to remove Using Bar; statement
Rename namespace Bar by a diffente name.
In my case, the foollowing compiler error occurred on a EF (Entity Framework) repository project on an Database.SetInitializer() call:
Member 'Database.SetInitializer<MyDatabaseContext>(IDatabaseInitializer<MyDatabaseContext>)' cannot be accessed with an instance reference; qualify it with a type name instead MyProject.ORM
This error arouse when I added a MyProject.ORM.Database namespace, which sufix (Database), as you might noticed, matches Database.SetInitializer class name.
In this, since I have no control on EF's Database static class and I would also like to preserve my custom namespace, I decided fully qualify EF's Database static class with its namepace System.Data.Entity, which resulted on using the following command, which compilation succeed:
System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(MyMigrationStrategy)
Hope it helps
YourClassName.YourStaticFieldName
For your static field would look like:
public class StaticExample
{
public static double Pi = 3.14;
}
From another class, you can access the staic field as follows:
class Program
{
static void Main(string[] args)
{
double radius = 6;
double areaOfCircle = 0;
areaOfCircle = StaticExample.Pi * radius * radius;
Console.WriteLine("Area = "+areaOfCircle);
Console.ReadKey();
}
}

Does static members prevent the instance class from being GC'ed?

Static members are not regarding the instance but the type itself.
But I was wondering :
If I have this class :
public class A
{
...
public static int MyInt{get;set;}
...
}
I can create of course new A()
But my question is :
Does the static member which is "stucked" to the type itself , prevents the instance from being GC'ed ?
Not necessarily. The static member belongs to the class itself, which CLR keeps as a Type object. If the static member was an object of type A, then the static member could keep that particular instance of A from being garbage collected.
public class Example
{
// this particular instance of Example will not be collected
private static readonly Example Default = new Example();
public void Foo()
{
// this instance *can* be collected after Foo returns
Example anotherInstance = new Example();
}
}
This behavior is useful for certain classes which aren't necessarily singletons but do have a "default" behavior that is stateless. One example where I use this is the ParseTreeWalker.Default field in the C# runtime library for the ANTLR 4 project. If you need the default behavior, you can use that instance without creating new objects, but you also have the option of creating your own instances of a class extending ParseTreeWalker to add your own behavior.
No, it does not. This can be easily shown by overwriting the finalizer.

Referencing non-static fields from static functions and vice versa impossible?

I want to programmatically determine the space I've got for some controls I want to create dynamically. So, I want to get the container's height and divide it by the number of rows (a constant).
I've got this function (this code is part of the form on which the panel named dynamicPanel lives):
private static int getControlHeightToUse() {
return (dynamicPanel.Height / NUMBER_OF_ROWS);
}
...which gives me the compile-time error, "*An object reference is required for the non-static field, method, or property RememberNextGen_CRLogins.CRLoginsMainForm.dynamicPanel'*"
I don't understand what it's trying to tell me/what it wants.
If I remove the "static":
private int getControlHeightToUse() {
return (dynamicPanel.Height / NUMBER_OF_ROWS);
}
...I then get the compile-time error, "*A field initializer cannot reference the non-static field, method, or property 'TitanNextGen_CRLogins.CRLoginsMainForm.getControlHeightToUse()'*"
...on the indicated line below:
public partial class CRLoginsMainForm : Form {
int controlHeight = getControlHeightToUse(); // <-- err
A static method has only direct access to static memebers of the class, if you want to use instance members of the class, you must pass in an instance of the class to the method (or have one available as a static as in the case of a singleton).
Thus, you can modify your method to take in the instance member that is preventing it from being able to be static:
private static int getControlHeightToUse(Panel thePanel)
{
return (thePanel.Height / NUMBER_OF_ROWS);
}
Then just pass in dynamicPanel on the call...
Instance methods, however, can access static members. Remember that static members are shared among all instances and exist even if no instance of the class exist. Thus they can't call instance members since they don't know which instance you are talking about.
pass dynamicPanel as parameter to static method
public partial class CRLoginsMainForm : Form {
int controlHeight = getControlHeightToUse(dynamicPanel);
change getControlHeightToUse as below
private static int getControlHeightToUse(Panel panel) {
return (panel.Height / NUMBER_OF_ROWS);
}
if you want to call non static method from static method you can do as below
public class Foo
{
// public method
public void Method1()
{
}
public static void Data2()
{
// call public method from static method
new Foo().Method1();
}
}

c# syntax help What 's coming after the constructor?

public Butler(IWeapon weapon): this(weapon, new Communicate())
{}
What does this(weapon, new Communicate()) mean?
It calls another constructor on the same type, passing in the weapon that was passed to this constructor, and a new Communicate object. I assume there is also something like:
// might actually be private
public Butler(IWeapon weapon, Communicate communicate) {...}
This approach is useful by allowing you to have multiple constructors, but only put the code in the most complex one. All the other constructors just pass the arguments (or defaults, as necessary) to the chosen constructor.
The chained constructor gets invoked before the body of the constructor that has the : this(...)
It calls a constructor in the same class but with different parameters, for example:
public class Test
{
public Test() : this("Richard")
{
}
public Test(string name)
{
}
}
It means Butler extends an instance of the current class where the weapon object passed as the argument, and a new instance of the Communicate object are passed to the class constructor.
it is calling another constructor with the signature Butler(IWeapon, ICommunicate).

Categories