There are two files A.cs and B.cs. There is a method fn() which is used in both the classes.
Method fn() is used in both class files. This increases code complexity if I need this method in many class files (say 100 files).
I know that we can call this method by creating an object for the class in which this method is defined. How can I share this function between two or more classes without creating an object every time for accessing this method?
Put the method in a static class:
public static class Utils
{
public static string fn()
{
//code...
}
}
You can then call this in A.cs and B.cs without creating a new instance of a class each time:
A foo = new A();
foo.Property = Utils.fn();
Alternatively, you could create a BaseClass that all classes inherit from:
public class BaseClass
{
public BaseClass() { }
public virtual string fn()
{
return "hello world";
}
}
public class A : BaseClass
{
public A() { }
}
You would then call fn() like so:
A foo = new A();
string x = foo.fn();
I hope the function isn't really called fn(), but actually named to what it does, like CalculateTotal(). Then you can extract this method into a class, say: TotalCalculator.
Now upon application startup, preferably using dependency injection, you create one instance of the class that gets shared between objects that require it. Like so:
class TotalCalculator
{
public int Calculate()
{
return 42;
}
}
class NeedsCalculator1
{
TotalCalculator _calculator;
public NeedsCalculator1(TotalCalculator calculator)
{
_calculator = calculator;
}
public void Foo()
{
_calculator.Calculate();
}
}
class NeedsCalculatorToo
{
TotalCalculator _calculator;
public NeedsCalculatorToo(TotalCalculator calculator)
{
_calculator = calculator;
}
public void Bar()
{
_calculator.Calculate();
}
}
Then you instantiate the calculator once, and pass it into the other classes' constructor:
TotalCalculator calculator = new TotalCalculator();
NeedsCalculator1 dependency1 = new NeedsCalculator1(calculator);
NeedsCalculatorToo dependency2 = new NeedsCalculatorToo(calculator);
You can now further abstract the calculator dependency by creating a base class containing the constructor and a protected TotalCalculator instance field, for example.
Assuming that this method is self contained, you could create a static class and put this method as a static method in it, which is in turn, called by the other classes.
If is is not self contained, you could try and declare it in some super class and let the other 100 classes extend that class.
Related
Recently, I had a need to process the private data contained in the base class using the methods of the child class. My base class could only contain domain-specific types (it only represents data). So first I decided to create a child-class in another project and implement the processing logic in it. But the problem is that once you create an instance of the base class, you can't cast it to the child type:
public class A
{
protected int member1;
public A(int value)
{
member1 = value;
}
}
public class B : A
{
public B (int value) : base(value)
{ }
public void DoSomething()
{
Console.Write(member1 * member1);
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
B obj2 = (B)obj1; // InvalidCastException
obj2.DoSomething();
}
}
And I started thinking towards extension methods. However, you can't just access the protected fields of the class from them. In the end, I tried to combine the two approaches.
Here's my solution:
Make sure that you are allowed to add new methods to your base class and that your class is not sealed.
Add protected static method which returns the protected member you need.
Create an Extension class for your base class.
In extension class create a private nested class.
Inherit your nested class from your base class.
Create static method in nested class and implement the processing logic in (you can call static protected method from base class to get protected member from base class).
Create extension method in extension class and call static method of nested class in it.
The sample code is shown below:
public class A
{
protected int member1 = 0;
public A() {}
public A(int value)
{
member1 = value;
}
protected static int GetProtectedMember(A objA)
{
return objA.member1;
}
}
public static class AExtensions
{
public static void DoSomething(this A objA)
{
B.DoSomething(objA);
}
private class B : A
{
public static void DoSomething(A objA)
{
// objA.member1 // it's not allowed
int protectedFromA = A.GetProtectedMember(objA);
int sqr = protectedFromA * protectedFromA;
Console.WriteLine(sqr);
}
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
obj1.DoSomething(); // 25
}
}
This way you can keep the classes that represent the data in a separate project and have multiple implementations of processing this data in different projects.
I have this generic class:
public abstract class FilterPage<T> where T : IResponse
{
protected List<T> apiResults;
public abstract List<T> Post();
}
And this class that inherites from FilterPage:
public class ExportImportPage : FilterPage<DemandExportReport>
{
public override List<DemandExportReport> Post()
{
return apiResults = API.Post<List<DemandExportReport>>(FilterReqtUrl);
}
}
public class DemandExportReport : IResponse
{
...
}
And here I have the class where I am doing my initializations:
class TestClass
{
public void Method1()
{
FilterPage<DemandExportReport> myInst = new ExportImportPage();
}
public void Method2()
{
// I want to use myInst here.
}
}
In TestClass, if I declare and initialize myInst in Method1() as FilterPage<DemandExportReport> myInst = new ExportImportPage(), it works fine. My problem is that I don't know the type at compile time. Instead of DemandExportReport I may use a different type. I want to initialize myInst in Method1() and then use it in other methods, being able to call myInst.Post(). So, how can I declare myInst without doing FilterPage<DemandExportReport> myInst;, as I want to use several types with FilterPage instead of DemandExportReport?
Note: If I create a non-generic base class, let's say BaseFilterPage, and then inherite FilterPage<t> from it, I am able to declare a BaseFilterPage instance class. The problem is that with that variable I don't have access to the Post() method. And I cannot move the Post() declaration to BaseFilterPage because it is a generic method.
I Am getting a warning message in my class, like
Add a Protected constructor or the static keyword to the class declaration
Solution
The error is gone after I tried both the below ways,
static class without constructor
public static class Program {
}
Non static class with protected using constructor
public class Program
{
protected Program() { }
}
Question:
So What is the difference between Static Class vs Protected Constructor which is mentioned in my above solution? And which one is best to use?
A static class doesn't need an instance to access its members. A static class cannot have instance members (e.g. public int MyNumber; is not allowed on a static class because only static members are allowed on a static class). Both instance and static members are allowed on a non-static class though. A class with a protected constructor can only have an instance created by itself or something that inherits from it.
public class Program
{
protected Program()
{
// Do something.
}
public static Program Create()
{
// 100% Allowed.
return new Program();
}
public void DoSomething()
{
}
}
public static class AnotherClass
{
public static Program CreateProgram()
{
// Not allowed since Program's constructor is protected.
return new Program();
}
}
public class SubProgram : Program
{
protected SubProgram()
{
// Calls Program() then SubProgram().
}
public new static Program Create()
{
// return new Program(); // We would need to move the SubProgram class INSIDE the Program class in order for this line to work.
return new SubProgram();
}
}
Program.Create(); // Can be called since Create is public and static function.
Program.DoSomething() // Can't be called because an instance has not been instantiated.
var test = Program.Create();
test.DoSomething(); // Can be called since there is now an instance of Program (i.e. 'test').
AnotherClass.CreateProgram(); // Can't be called since Program's constructor is protected.
SubProgram.Create(); // Can be called since SubProgram inherits from Program.
As for performance, this distinction doesn't really have much to do with performance.
You probably only have static members in the class and the code analyser assumes that your intention is to not be able to create instances of the class so it is asking you to either make the class static
public static class Program {
//...static members
}
or put a protected/private constructor
public class Program {
protected Program { //OR private
}
//...static members
}
to prevent instances of that class from being initialized.
A static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated.
Reference Static Classes and Static Class Members (C# Programming Guide)
The protected constructor means that only derived classes can call the constructor
and a private constructor wont allow any other classes to initialize the class with a private constructor
A static constructor is called when the class type is instantiated. The protected constructor is called when an instance of a class is created. The protected part means only classes that inherit the class can call it.
Static Constructor: Called once when the class type is instantiated and is used to initialize static members. Does not create an instance of the class.
Protected Constructor: A constructor that can be called only by the class or a class that inherits it.
The best practices for this is that you should have a static constructor for initializing static members and a protected constructor if you only want classes that inherit to be able to create an instance of your class. You can have both.
public class MyClass
{
static readonly long _someStaticMember;
private bool _param;
static MyClass()
{
//Do Some Logic
_someStaticMember = SomeValueCalculated;
}
protected MyClass(bool param)
{
_param = param;
}
}
public class ChildClass: MyClass
{
public ChildClass(bool param) : base(param);
}
public class NotChildClass
{
public MyClass someObject = new MyClass(true); //Will Fail
}
I have a base and derived class like so:
public abstract class MyBase
{
protected string _data;
protected string GetData_Internal() {return _data;}
protected abstract void SetData(string data);
}
public class MyDerived : MyBase
{
protected override void SetData(string data) {_data = "my data";}
public static string GetData()
{
var instance = new MyDerived();
return instance.GetData_Internal();
}
}
The desired usage of this class is like this:
string data1 = MyDerived.GetData();
string data2 = MyDerived2.GetData(); // another class dervied from MyBase
I can't make the classes static, because static classes and derived classes don't play well together. So I made the function GetData() static, and this allows me to use the class like I want to.
I am going to have multiple classes that all identical to MyDerived, except for the data values set in SetData().
I would like to move GetData() out of the derived class and into the base class so that I'm not duplicating that code in every single derived class.
I can't figure out how to do that, because a static method in the base class has no idea what type of object to new up.
So, is there any way to do what I'm trying to do, keeping a static interaction with the class, while avoiding code duplication to make it happen?
If you are working with static data, maybe what you need are singleton objects that can be instantiated only once. They have the advantage of supporting inheritance and interface implementation, as well as being accessible statically. Also, unlike static classes, they can be passed as arguments to methods and stored in fields, properties and variables.
You can use properties instead of getter and setter methods. This simplifies your base class:
public abstract class MyBase
{
public string Data { get; set; }
}
You can implement the singleton pattern like this:
public class MyDerived : MyBase
{
#region Singleton Pattern
public static readonly MyDerived Instance = new MyDerived();
private MyDerived()
{
}
#endregion
}
Create a public static readonly field that returns the only instance of the class and make the constructor private in order to forbid creating instances outside of the class itself. The constructor can also initialize the value of Data if required.
You can use the singletons like this:
MyDerived.Instance.Data = "my data";
string data = MyDerived.Instance.Data;
MyDerived2.Instance.Data = "my data 2";
...
See also: Implementing Singleton in C# for various ways of implementing the singleton pattern.
First, I am not completely sure what it is you are trying to accomplish. So, I am making no comment on if any of this is a good idea. You can get behavior that acts somewhat like overridden methods on base classes with statics. Instead, you overwrite the base then call into it. I do something similar to this for fetching instances or collections of instances from the class:
public class Dog
{
public static Dog GetById(int dogId)
{
//Return dog
}
}
public class Lab : Dog
{
public new static Lab GetById(int dogId)
{
//Return same dog, as a lab
}
}
A quick and terrible, but hopefully useful, version might start like the following. I might be able to make it into something practical if I understand your intentions a bit better.
public abstract class MyBase
{
public static string GetData()
{
return "BASE STUFF";
}
}
public class MyDerivedA : MyBase
{
protected const string MySpecialData = "AAAAAA";
public new static string GetData()
{
return MyBase.GetData() + MySpecialData;
}
}
public class MyDerivedB : MyBase
{
protected const string MySpecialData = "BBBBBBB";
public new static string GetData()
{
return MyBase.GetData() + MySpecialData;
}
}
I have error
Cannot access a non-static member of outer type 'Project.Neuro' via
nested type 'Project.Neuro.Net'
with code like this (simplified):
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = OtherMethod(); // error is here
}
}
public int OtherMethod() // its outside Neuro.Net class
{
return 123;
}
}
I can move problematic method to Neuro.Net class, but I need this method outside.
Im kind of objective programming newbie.
Thanks in advance.
The problem is that nested classes are not derived classes, so the methods in the outer class are not inherited.
Some options are
Make the method static:
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = Neuro.OtherMethod();
}
}
public static int OtherMethod()
{
return 123;
}
}
Use inheritance instead of nesting classes:
public class Neuro // Neuro has to be public in order to have a public class inherit from it.
{
public static int OtherMethod()
{
return 123;
}
}
public class Net : Neuro
{
public void SomeMethod()
{
int x = OtherMethod();
}
}
Create an instance of Neuro:
class Neuro
{
public class Net
{
public void SomeMethod()
{
Neuro n = new Neuro();
int x = n.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
you need to instantiate an object of type Neuro somewhere in your code and call OtherMethod on it, since OtherMethod is not a static method. Whether you create this object inside of SomeMethod, or pass it as an argument to it is up to you. Something like:
// somewhere in the code
var neuroObject = new Neuro();
// inside SomeMethod()
int x = neuroObject.OtherMethod();
alternatively, you can make OtherMethod static, which will allow you to call it from SomeMethod as you currently are.
Even though class is nested within another class, it is still not obvious which instance of outer class talks to which instance of inner class. I could create an instance of inner class and pass it to the another instance of outer class.
Therefore, you need specific instance to call this OtherMethod().
You can pass the instance on creation:
class Neuro
{
public class Net
{
private Neuro _parent;
public Net(Neuro parent)
{
_parent = parent;
}
public void SomeMethod()
{
_parent.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
I think making an instance of outer class in inner class is not a good option because you may executing business logic on outer class constructor. Making static methods or properties is better option. If you insist making an instance of outer class than you should add another parameter to outer class contructor that not to execute business logic.