using static methods with properties - c#

I found out about properties a couple of days ago(not sure if I understood how to use them very well). So I decided to make some tests.
so here's what Ive done :
I created a class that contains some properties such as :
public string _string1 { get; set; }
public string _string2 { get; set; }
and then I created a method in the same class lets say like this :
public static string Example()
{
switch(_string1.length > _string2.length)
{
case true :
return _string1;
break;
default : return _string2;
}
}
just a stupid example to understand a bit
and then I called the method from the main class after that I got a couple of errors :
An object reference is required for the non-static field, method, or property 'xxx.properties._string1.get'
Well its certainly a stupid mistake but I'm new to c# and I could use some assistance.

You need to make your properties static too:
public static string _string1 { get; set; }
public static string _string2 { get; set; }
Essentially a static method has no state. Those fields when declared in a non-static manner are essentially like a state, therefore it can't access them. By marking them static you say this is the Global value for the AppDomain.
One thing to be wary of using static fields like this however is if you start using any sort of threading and try to store state then you can end up with nasty issues to debug because you've no idea what state you're shared resources are in.
A way to protect against this (if you don't need state) is to define these as constants fields instead. Then you can't modify them, but means you need not worry about someone changing them when you didn't expect it.
public const string _string1;
public const string _string2;

A static method can always access other static members only. Now since your properties are not static hence your static method cannot access/manipulate them.
You can make these fields as static and then the error will go away. Once these are static no object reference would be required to access them.
They can then be simply accessed through the classname itself.
for example
public class YourClass
{
public static string _string1 { get; set; }
public static string _string2 { get; set; }
public static string Example()
{
switch(_string1.length > _string2.length)
{
case true :
return _string1;
break;
default : return _string2;
}
}
}
Now in your program:
YourClass._string1="some string"; // You can access the static properties with class name
YourClass._string2="some other string";
YourClass.Example() // You can call the static function with class name.

It's all about instance versus static scope. Whilst the examples above make your error go away, it is important to understand when to use static methods, variables, properties versus instance ones. In fact, you could say that using static members is not really a pure OOP practice. Most of the time, static members are misused because people misunderstand these OOP basics.
Static methods and variables are shared amongst all object instances for your class. Therefore, in most scenarios, you will need to have a specific requirement to have a static method/variable, such as keeping a total count of objects in a static variable which would be accessible across all your object instances.

You can create a new instance of the class where variables are.
public class YourClass
{
public string _string1 { get; set; }
public string _string2 { get; set; }
...
}
public static string Example()
{
YourClass yourClass = new YourClass();
switch(_string1.length > _string2.length)
{
case true :
return yourClass._string1;
break;
default : return yourClass._string2;
}
}

Related

Using non-static code with static main method

I'm having trouble with getting my static main method to play nicely with my backend code.
Here's the backend stuff:
public interface ITicketGenerationService
{
string CreateTicket(DateTime begin, DateTime end);
}
public class TicketGenerationService : ITicketGenerationService
{
public static IRepository<Ticket> Repository { get; set; }
public TicketGenerationService(IRepository<Ticket> repository)
{
Repository = repository;
}
public string CreateTicket(DateTime begin, DateTime end)
{
//do stuff with Repository
//return status string to Main method
}
}
Here's where my console application begins:
public class TicketMain
{
public ITicketGenerationService TicketGenerationService { get; set; }
static void Main(string[] args)
{
var priorityOneTickets = TicketGenerationService.CreateTicket(begin, end);
}
}
So I initially get this error:
An object reference is required for the non-static field, method, or
property 'TicketMain.TicketGenerationService'
If I change CreateTicket to static, I get another error:
TicketGenerationService does not implment interface member
ITicketGenerationService.CreateTicket(DateTime, DateTime).
ITicketGenerationService.CreateTicket(DateTime, DateTime) cannot
implement an interface member because it is static.
If I try to add this:
var ticketingService = new TicketGenerationService();
to the main method, I'm afraid that will mess with my dependency injection(autofac).
I understand the errors, but I can't make everything static, and I'm afraid if I start instantiating, I'll lose all my data I gain via dependency injection.
Is there anyway around this?
Thanks!
It's not the TicketGenerationService.CreateTicket method that the error is referring to, it's your TicketGenerationService property in the TicketMain class.
You just need to change your property to static:
public static ITicketGenerationService TicketGenerationService { get; set; }

How can I extend a form class to access global variables without having to specify which class it belongs to?

I'm trying to create some global variables that I can access across all classes in my program and use them as if they exist in the same context of each class, i.e. without typing 'gVariables.'
class gVariables
{
public static string VariableA;
public static int VariableB;
public static byte[] VaraibleC;
public static bool AppIsClosing = false;
}
This works in a standard class:
public class SomeClass : gVariables
{
private void SomeMethod()
{
//Dont need to type 'gVariables.'
VariableA = "FooBar";
VariableB = 1024;
}
}
But how can I do this in a class that inherits System.Windows.Forms.Form?
You can create a BaseForm that inherits from Form. And then in each of your Forms (e.g. DerivedForm) you can inherit from the BaseForm. For example:
public class BaseForm : Form
{
public static string VariableA;
public static int VariableB;
public static byte[] VaraibleC;
public static bool AppIsClosing = false;
}
public class DerivedForm : BaseForm
{
}
One way would be to make a base class that has all the globals as members, as Donal has shown you. But as you have said in the comments, you cannot have a common base class for all your classes.
I will tell you a way you can do this, but I am not recommending that you should do this. What I am going to tell you is a way to simulate multiple inheritance in C# (again, not recommended if you do not have a good reason), so you can inherit both your global variables class and the natural parent class.
You can use an interface, and make all your classes implement that interface. To make examples shorter, I will choose only one variable: AppIsClosing.
interface IGlobalVariables
{
public bool AppIsClosing { get; set; }
}
You should have your class containing global variables, which implements IGlobalVariables. To make sure that only one instance is there, we will also implement the singleton pattern.
class GlobalVariables : IGlobalVariables
{
private bool _appIsClosing = false;
private static GlobalVariables _instance = new GlobalVariables();
private GlobalVariables() {}
public static Instance {
get { return _instance }
}
public bool IGlobalVariables.AppIsClosing
{
get { return this._appIsClosing; }
set { this._appIsClosing = value; }
}
}
Then in all other classes, you can do this:
class SomeClass : WhateverYouWantTheParentClassToBe, IGlobalVariables
{
public bool IGlobalVariables.AppIsClosing
{
get { return GlobalVariables.AppIsClosing; }
set { GlobalVariables.AppIsClosing = value; }
}
// other code
}
Assuming you heavily use global variables, now you can refer to the global variable as just AppIsClosing anywhere in your SomeClass.
Your requirement to use global variables (I believe) is not some evil use of global variables. Global variables are bad when you make int temp a global variable (or any other variable that should be local).
The problem I see with my approach is, you can never tell when a member of GlobalVariables is accessed. For example if we try to find references of GlobalVariables.AppIsClosing, Visual Studio will show us a bunch of IGlobalVariables.AppIsClosing implementations, which is utterly useless.
Just use your global class. Having to type few characters is one of the worst reasons to make this kind of awkward design.
I am showing this pattern to you because we had to port a software framework that was written in a legacy language which had multiple inheritance. And this is what we did. We simulated multiple inheritance by interfaces and object aggregation. I think we had a good reason there to use this kind of awkward design patterns.

c# correct way to access private constant on other class

If I have a class
public class Person
{
private const string MyConst = "SomeValue";
[MyAttribute(MyConst)]
public string Name {get;set;}
}
and inside other class I would like to access MyConst what would be the best way to do so, keeping all encapsulated? Is it correct Person class?
If you wish to access MyConst from another class then you are no longer encapsulating it. Adding properties or method calls around this will not mean it is encapsulated. It's a constant. It cannot change. So either its publicly accessible or it's not. If another class needs access, make it internal or public.
Anything else is somewhere between denial and a code smell.
It all depends on the protection you need on MyConst. If no body should be able to read or write this property other than Person then you shouldn't expose it through either Get or Set methods. If everybody can read but cant write this, then you can expose it through a read only property. If only one class (e.g. ClassB) can read it then you can provide a function in Person that takes a ClassB object and passes the private Const to it:
public class ClassB
{
private string ConstValue {get; set;}
public void SetConstValue(string constValue)
{
ConstValue = constValue;
}
public void GetConstFromPerson(Person p)
{
p.GetConstValue(this);
}
}
public class Person
{
private const string MyConst = "A";
public void GetConstValue(ClassB obj)
{
//todo: contract validations
obj.SetConstValue(MyConst);
}
}
[Edit]
Another solution is to define the constant as Internal and only have Person and CLassB in the assembly
make a public property that returns MyConst?
public string MyPublicConst {get{ return MyConst;} private set; } - but why do you want to do this?
You can have it public (Duh!), you can use a property to encapsulate it if you are planning on changing it from a constant to something else, or you could have a method that return it to you.
class Encapsulation{
private string a;
public string AccessValue(){
return a;
}
}
you can do that to any variable I think, for sure the simple ones.
This is a public method from the same class that returns the same value of the private string.
In that way you can get the value from outside the class without declare it as public.
To reach it from another class you can just write:
class Player{ string b = Encapsulaion.AccessValue()}

What is the best way to define a static property which is defined once per sub-class?

I wrote the following console app to test static properties:
using System;
namespace StaticPropertyTest
{
public abstract class BaseClass
{
public static int MyProperty { get; set; }
}
public class DerivedAlpha : BaseClass
{
}
public class DerivedBeta : BaseClass
{
}
class Program
{
static void Main(string[] args)
{
DerivedBeta.MyProperty = 7;
Console.WriteLine(DerivedAlpha.MyProperty); // outputs 7
}
}
}
As this console app demonstrates, the MyProperty property exists once for all instances of BaseClass. Is there a pattern to use which would allow me to define a static property which will have allocated storage for each sub-class type?
Given the above example, I would like all instances of DerivedAlpha to share the same static property, and all instances of DerivedBeta to share another instance of the static property.
Why am I trying to do this?
I am lazily initializing a collection of class property names with certain attributes (via reflection). The property names will be identical for each derived class instance, so it seems wasteful to store this in each class instance. I can't make it static in the base class, because different sub-classes will have different properties.
I don't want to replicate the code which populates the collection (via reflection) in each derived class. I know that one possible solution is to define the method to populate the collection in the base class, and call it from each derived class, but this is not the most elegant solution.
Update - Example of what I'm doing
At Jon's request, here's an example of what I'm trying to do. Basically, I can optionally decorate properties in my classes with the [SalesRelationship(SalesRelationshipRule.DoNotInclude)] attribute (there are other attributes, this is just a simplified example).
public class BaseEntity
{
// I want this property to be static but exist once per derived class.
public List<string> PropertiesWithDoNotInclude { get; set; }
public BaseEntity()
{
// Code here will populate PropertiesWithDoNotInclude with
// all properties in class marked with
// SalesRelationshipRule.DoNotInclude.
//
// I want this code to populate this property to run once per
// derived class type, and be stored statically but per class type.
}
}
public class FooEntity : BaseEntity
{
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_A { get; set; }
public int? Property_B { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_C { get; set; }
}
public class BarEntity : BaseEntity
{
public int? Property_D { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_E { get; set; }
public int? Property_F { get; set; }
}
Desired end result
Accessing FooEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_A",
"Property_C"
}
Accessing BarEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_E"
}
Two possible approaches:
Use attributes; decorate each subclass with an attribute, e.g.
[MyProperty(5)]
public class DerivedAlpha
{
}
[MyProperty(10)]
public class DerivedBeta
{
}
That only works when they're effectively constants, of course.
Use a dictionary:
var properties = new Dictionary<Type, int>
{
{ typeof(DerivedAlpha), 5) },
{ typeof(DerivedBeta), 10) },
};
EDIT: Now that we have more context, Ben's answer is a really good one, using the way that generics work in C#. It's like the dictionary example, but with laziness, thread-safety and simple global access all built in.
Jon has a good solution as usual, although I don't see what good attributes do here, since they have to be explicitly added to every subtype and they don't act like properties.
The Dictionary approach can definitely work. Here's another way to do that, which explicitly declares that there will be one variable per subclass of BaseEntity:
class FilteredProperties<T> where T : BaseEntity
{
static public List<string> Values { get; private set; }
// or static public readonly List<string> Values = new List<string>();
static FilteredProperties()
{
// logic to populate the list goes here
}
}
The drawback of this is that it's rather difficult to pair with a GetType() call such as you might use in methods of BaseEntity. A Dictionary, or wrapper thereto which implements lazy population, is better for that usage.
I just recently needed this same thing and came across this question. I think Jon's and Fried's ideas to use a Dictionary are on the right track but don't quite hit what I was looking for so I thought I'd show my own complete and very easy to extend implementation.
public class TypeStaticProperty<T>
{
T _defaultValue;
Dictionary<Type, T> _values = new Dictionary<Type, T>();
public TypeStaticProperty(T defalutValue = default)
{
_defaultValue = defalutValue;
}
public T Get(object caller)
{
lock (_values)
{
if (_values.TryGetValue(caller?.GetType(), out T val))
return val;
else
return _defaultValue;
}
}
public void Set(object caller, T val)
{
lock (_values)
_values[caller?.GetType()] = val;
}
}
And to demonstrate:
class TestBaseClass
{
static TypeStaticProperty<int> _property = new TypeStaticProperty<int>();
public int Property
{
get => _property.Get(this);
set => _property.Set(this, value);
}
}
class TestClass1 : TestBaseClass
{
}
class TestClass2 : TestBaseClass
{
}
class Program
{
static void Main(string[] args)
{
TestClass1 test1a = new TestClass1();
TestClass1 test1b = new TestClass1();
test1a.Property = 1;
test1b.Property = 2;
TestClass2 test2a = new TestClass2();
TestClass2 test2b = new TestClass2();
test2a.Property = 3;
test2b.Property = 4;
Console.WriteLine($"test1a.Property = {test1a.Property}");
Console.WriteLine($"test1b.Property = {test1b.Property}");
Console.WriteLine($"test2a.Property = {test2a.Property}");
Console.WriteLine($"test2b.Property = {test2b.Property}");
}
}
Output:
test1a.Property = 2
test1b.Property = 2
test2a.Property = 4
test2b.Property = 4
So while you still need a class instance to access and set the property, the value will always be the same across all instances of that precise type. (This includes generics too; Foo<int> will be seen as a different type than Foo<string>). This has the huge advantage over Fried's example in that you don't need to know at compile time the precise type whose "static" value you're looking for when accessing or setting.
PS - For full disclosure, this was heavily inspired by the WPF source code, which uses a very similar pattern for DependencyProperty's and all kinds of other internal bells and whistles designed to improve performance and reduce memory footprint.

static abstract class

I need a way to create a static class where some constants can be case specific, but hard-coded.
What I really want to do is have a class where several constants are provided when the class is extended - I want the 'constants' hard-coded. I figured I will make the some abstract properties and define the get { return constant; } when extending the class.
I know that is not possible, so now I am facing two options and am wondering what would be best and why (if there are options I'm missing please let me know!)
Create a static class with nullable fields and throw an exception if the fields are null when the static method is called.
Give up the static class. Have a non-static class with abstract properties and create an instance of the object wherever I need it even though all the functionality really is static.
I know this might be subjective and case-dependant, however I am going around in circles when thinking about this and could really do with some external input. That plus I hope there might be away of doing what I want and I'm just thinking about this wrong.
Update: Code: I will try to write some code that describes what I'd like to accomplish. I know this code can't work!
Imagine that the abstract class Calculation is in a dll, used by many projects. The functionality is the same for all of them, just the Constant varies from project to project.
public abstract static class Calculation
{
private abstract int Constant { get; } //The constant is unknown at this time
public static int Calculate(int inputValue)
{
return inputValue * Constant;
}
}
The class Calc is defined in a separate project where the functionality is needed and the Constant is known.
public static class Calc : Calculation
{
private override int Constant { get { return 2; }
}
...
static class Program
{
[STAThread]
static void Main()
{
//At some point:
int result = Calc.Calculate(6);
}
}
I suppose the simplest way would be to create a non-static class and create an instance, however I fear having several instances of the class could be expensive and would like to prevent that if possible.
I can't see how I could write this as a singleton pattern without writing it again in each project - having only the Nested class in the dll. That doesn't prevent the implementor to just create an ordinary class and is likely to restart the debate for every project where the code is used.
Update #2 : What I ment with option one is this:
Class in a dll:
public static class Calculation
{
public int? Constant {get; set;}
public static int Calculate(int inputValue)
{
if (Constant == null)
throw new ArgumentNullException();
return inputValue * (int)Constant;
}
}
Usage of the function in a seperate project:
static class Program
{
[STAThread]
static void Main()
{
//At some point:
Calculation.Constant = 2;
int result = Calc.Calculate(6);
}
}
Option one is very simple and elegant, what bothers me about it that nothing forces the implementor to set the Constant. I fear an (admittedly unlikely) scenario where an obscure corner case will cause the property to not be set and for the code to fail (and Constant beeing the last suspect)...
You could make non-static classes that follow singleton, ensuring only one instance of the object ever to exist. I guess that could be the next best thing.
You can't want static and inheritance at the same time ! It simply does not make sense !
If you need to override behavior, you need inheritance !
If you want simplicity of call (one of the advantage of statics), you can use Factory (or singleton if only one instance is needed)
My guess is that you probably have to rethink your model. This set of constants of yours probably represent something that you could extract in a separate class then pass this class to your static method. Would that fit your needs ?
Edit
To your code sample:
public abstract static class Calculation
{
public static int Constant { get; set; }
public static int Calculate(int i) { return i * Constant; }
}
// ...
Calculation.Constant = 6;
Calculation.Calculate(123);
Somewhat more general:
public abstract static class Calculation
{
public struct Context
{
public int Constant, SignificantDigits;
public bool Radians;
}
public static int Calculate(int i, Context ctx) { return i * ctx.Constant; }
}
// ...
Calculation.Calculate(123, new Calculate.Context { Constant = 6 });
First idea:
The closest I can think of is generics:
public interface ISpecifics
{
void DoSomething();
string SomeProp { get; }
}
public static class Static<S>
where S : ISpecifics, new()
{
public static string ExerciseSpecific()
{
var spec = new S();
spec.DoSomething();
return spec.SomeProp;
}
}
Or if you really need a single static type
public static class Static
{
public static string ExerciseSpecific<S>()
where S : ISpecifics, new()
{
var spec = new S();
spec.DoSomething();
return spec.SomeProp;
}
}
Does that help?
I needed pretty much the same thing, so first I made a non-static class with all the functionality.
Then, a static class which instantiates one such non-static class in its static constructor.
Then any of the static methods calls the respective instance methods.
Something like this:
public class CalculationInstance
{
private int constant;
public int Calculate(int inputValue)
{
return inputValue * constant;
}
public void AnyOtherMethod()
{
....
}
public CalculationInstance(int constant)
{
this.constant=constant;
}
}
public static class Calculation
{
const int CONSTANT=2;
private CalculationInstance calc;
static Calculation()
{
calc=new CalculationInstance(CONSTANT);
}
public static int Calculate(int inputValue)
{
return calc.Calculate(inputValue);
}
public static void AnyOtherMethod()
{
calc.AnyOtherMethod();
}
}
static class Program
{
[STAThread]
static void Main()
{
//At some point:
int result = Calculation.Calculate(6);
}
}
I feel this doesn't make sense here, a static class is by default sealed class which means it is sealed for inheritance. So please don't consider having static with abstract.
You can have an abstract class and the child class can inherit and override the methods.

Categories