Easy way to share private variables with constructed class in C# - c#

So I'm aware of several ways to make private fields accessible to other classes, I just I feel like their must be an easier way because I could do it easier in C++ with pointers.
Basically, I have a class with a large number of integers, that then creates a number of classes that use these integers. But each class only uses a few integers each. What I want is to allow each class to access only the variables that they need, but have all the remaining integers be unaccessible.
Basically what I would do in C++ is:
class PrivateClass
{
private:
int a, b, c, d;
public:
void DoStuff();
};
And then
void DoStuff()
{
ClassOne class_one(&a, &b);
ClassTwo class_two(&c, &d);
//stuff
}
So then class_one has access to the values of a and b, while class_two has access to the values of c and d. (Also, if I've made any errors in my code forgive me, it has been a while since I've actually written in C++)
Given how easy it is to do there, it makes me feel (perhaps erroneously) like there must be a similarly easy method in C#. If not, I'll mostly just make an indexer to encapsulate the variables so that they can be accessed that way.
Edit: Basically I'm getting that I should just use properties like I've been weirdly avoiding. I don't mind making properties for a few fields, but for some reason doing it for 30 or so just feels wrong, like there should be a better way.

The idea of sharing private variables with another class doesn't quite make sense. There are various access modifiers, but that doesn't help if you want one class to have access to certain members, another class to have access to different members, and so forth.
So the first question is how to share variables. Typically we do that with properties.
In this example another class can read A but can't change it. Another class can both read and write B. There is no property for changing _c.
If we want to split hairs, nothing outside the class can actually read or change the variables. They can only access the property, and the property reads/writes the variable.
(You can also do this with auto-properties. You don't need a variable and a separate property. But that's irrelevant for now.)
class PrivateClass
{
private int _a;
private int _b;
private int _c;
public int A => _a;
public int B
{
get { return _b; }
set { _b = value; }
}
};
Next you want to be able to control which classes can "see" which variables.
As long as there are properties, you can't absolutely prevent someone from writing code that calls them. But you can control how one class "sees" another class.
Here's a contrived example. These types don't make much sense.
public class PublicTransportVehicle : IPublicTransport, IMotorVehicle
{
public int PassengerCapacity { get; private set; }
public int PassengerCount { get; set; }
public int AxleCount { get; private set; }
}
public interface IPublicTransport
{
int PassengerCapacity { get; }
int PassengerCount { get; set; }
}
public interface IMotorVehicle
{
int AxleCount { get; }
}
The PublicTransportVehicle class has three int properties. Two are read-only. One is read-write. (I used auto-properties instead of variables. This just means that if set is private then only the class itself can set the property.)
Now I can write a class with a method that takes an argument of type IPublicTransport. I can pass an instance of PublicTransportVehicle or any other class that implements the interface. But the method only sees IPublicTransport. The only properties it knows about are the ones exposed by that interface.
I can write another method that takes an argument of type IMotorVehicle and it only interacts with the properties defined in that interface.
I can pass an instance of PublicTransportVehicle to either method because it implements both interfaces, but each one sees it differently.
Can we absolutely prevent the caller from accessing properties we didn't want it to access? That's a lot harder. For example, a class could do this:
public void DoSomethingWithMotorVehicle(IMotorVehicle motorVehicle)
{
var publicTransportVehicle = motorVehicle as PublicTransportVehicle;
if (publicTransportVehicle != null)
{
publicTransportVehicle.PassengerCount = 1000;
}
}
But we usually can't and shouldn't bother trying to exercise complete control over that. It's practically impossible. The idea is to communicate which properties and methods consumers are expected to interact with. We do that by deliberately making them accessible. If someone wants to something weird like casting an object or using reflection there's not a lot we can do. Unless it's a serious security-related matter we don't need to worry about that.

Private fields, methods, properties, constructors, and events are all meant to be used by the class only. If you want to access these fields from other classes, you can make something like this:
using System;
namespace SharePrivateFields
{
class Supervisor
{
void DoStuff()
{
var subject = new Subject();
var first = new First(subject);
var second = new Second(subject);
}
}
class Subject : IFirstSubject, ISecondSubject
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
interface IFirstSubject
{
int A { get; set; }
int B { get; set; }
}
interface ISecondSubject
{
int C { get; set; }
int D { get; set; }
}
class First
{
private IFirstSubject _subject;
public First(IFirstSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // Completely correct
Console.WriteLine(_subject.C); // `IFirstSubject` does not contain definition for `C`
}
}
class Second
{
private ISecondSubject _subject;
public Second(ISecondSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // `ISecondSubject` does not contain definition for `A`
Console.WriteLine(_subject.C); // Completely correct
}
}
}
However, we're now treading waters of Abstract Factory Design Pattern, which is a more desirable approach in this case.
I'm convinced that the C++ implementation you're mentioning is a flawed design, so it's a reason why you can't make it easy in C# (if we're being completely honest - you can, read about Unsafe code, pointer types, and function pointers; but it's 99% of a time taboo for C# code).
So I suggest you learn about Abstract Factory or at least use my solution for your use-case.

Make the method static and send the corresponding instance to it, then you can access the data you want.
Static Void DoStuff(PrivateClass instance)
{
ClassOne class_one(instance.a, instance.b);
ClassTwo class_two(instance.c, instance.d);
//stuff
}
But the reality is that it is wrong, you should either add reading and writing properties to your variables to be able to send them to DoStuff from outside as a parameter.
//in Main
PrivateClass pClass = new PrivateClass(1,30,2,19);
DoStuff(pClass.A, pClass.B, pClass.C, pclass.D);
//in PrivateClass
namespace Test
{
class PrivateClass
{
private int a;
private int b;
private int c;
private int d;
public PrivateClass(int a, int b, int c, int d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
public int A
{
get
{
return this.a;
}
set
{
this.a = value;
}
}//etc
public static void DoStuff(int a, int b, int c, int d)
{
ClassOne class_one(a, b);
ClassTwo class_two(c, d);
//stuff
}
}
}

Related

C# access children's static member in parent

I have a class Foo, which is a base class for a lot other classes such as Bar and Baz, and I want to do some calculation within Foo using the static members in Bar and Baz, as shown below:
public class Foo{
public result1 {
get{
return field1;
}
}
}
public class Bar : Foo{
public const int field1 = 5;
}
public class Baz : Foo{
public const int field1 = 10;
}
The only solution I can think of is wrap all the fields in a container, add an extra identifier for each object, and use a function to return the fields, like so
Bar : Foo{
public readonly int id = 0;
public static Wrapper wrapper;
}
public Wrapper GetWrapper(int id){
switch(id){
case 0:
return Bar.wrapper;
}
}
However, as you can see, I need to maintain one additional class and function, and I'd rather not to fragment my code. Is there any alternative?
Edit
What you are asking for, i.e. accessing a static or const value in a subclass from a base class is technically possible, but doing so will violate the principals of good SOLID OO design. Also, since you will need an instance of a specific subclass in order to be able to 'reason over' the type of the subclass in order to obtain the appropriate field1, there's little point approaching this problem statically.
Instead, the common, cleaner, approach here is to use subtype polymorphicism which will allow a calling method in the base class, or a method in an external class altogether, to access the appropriate value for 'field1' based on the subclass. This allows control over the value returned to remain inside the appropriate subclasses (i.e. as per your words, the code won't become "fragmented").
Alternative solution using subclass polymorphicism (recommended)
A subclass polymorphic approach (i.e. with the virtual/abstract and override keywords) will allow you to encapsulate the retrieval of a value (or object) which is customizable for each subclass. Here, the abstraction remains conceptually at "give me an integer value", and then the sub-class-specific implementations of 'how' to return the value can be abstracted (hidden) from the caller. Also, by marking the base property as abstract, you will force all subclasses to implement the property, so that the requirement to provide a value isn't forgotten about.
i.e. I would recommend a polymorphic approach like this:
public abstract class Foo
{
public abstract int Result { get; }
}
public class Bar : Foo
{
// This is implementation specific. Hide it.
private const int field1 = 5;
public override int Result
{
get { return field1; }
}
}
public class Baz : Foo
{
public override int Result
{
// No need for this implementation to be a constant ...
get { return TheResultOfAReallyComplexCalculationHere(); }
}
}
If there are no other reusable concrete methods on the base class Foo, then you could also model the abstraction as an interface, with the same effect:
public interface IFoo
{
int Result { get; }
}
Approaching this problem without polymorphicism (Not recommended)
Any compile-time attempt to access static fields on subclasses will typically require code somewhere to switch (or map) on the actually type of the subclass instance, e.g.:
public class Foo
{
public int result1
{
get
{
switch(this.GetType().Name)
{
case "Bar":
return Bar.field1;
case "Baz":
return Baz.field1;
default:
return 0;
}
}
}
public void MethodRequiringValueFromSubclass()
{
Console.WriteLine(result1);
}
}
public class Bar : Foo
{
public const int field1 = 5;
}
public class Baz : Foo
{
public const int field1 = 10;
}
The problem here is that the Open and Closed principal is violated, as each time a new sub class is added, the result1 method would need to be changed to accomodate the new class.
I'd suggest to use abstract function rather that using static member.
public abstract class Foo{
public result1 {
get{
return get_field1();
}
}
protected abstract int get_field1();
}
public class Bar : Foo{
public const int field1 = 5;
protected override int get_field1() { return field1;}
}
public class Baz : Foo{
public const int field1 = 10;
protected override int get_field1() { return field1;}
}
You either add constructor parameter to your Foo class which can be passed from inheritors, thus you don't need extra classes also you'll have less coupling
public class Foo
{
private readonly int _field1;
public Foo(int field1)
{
_field1 = field1;
}
}
or you can use it exactly from inheritors type as static/const members are members of class type
public class Foo
{
public result1
{
get
{
return Bar.field1;
}
}
}
but this gives your code less flexibility and more coupling.
Also you have an option by using virtual properties which you can implement in derrived classes and use in base:
public class Foo
{
public virtual int Field { get { return 0; } }
}
Instead of making Foo abstract as other answers suggested you can use virtual and override result1 in each child class
public class Foo
{
public virtual int result1 { get; }
}
public class Bar : Foo
{
public const int field1 = 5;
public override int result1
{
get { return field1; }
}
}
public class Baz : Foo
{
public const int field1 = 10;
public override int result1
{
get { return field1; }
}
}
If you want default result1 to return something else than 0 you can give it another value
public class Foo
{
public virtual int result1 { get; } = -1;
}
I always feel like a jerk when I answer my own question... Yet didn't see what I was expecting so I might as well just share what I've got after a night of mind boggling.
The reason I don't want to make the calculation abstract/virtual is because there are many subclasses and the formula is the same for all of them. I just refuse to type the same code 10-20 times repeatedly.
Couldn't make the static fields non static either, as they should be accessible at a class level plus they can get big, and they are the same for all instances.
The only solution I can come up that minimizes code fragment is something like this
public class Foo {
public class Wrapper {
Fields...
}
public Wrapper wrapper; // reference
public int result1 { get; }
}
public class Bar : Foo {
public static Wrapper subclassWrapper; // put in the implementation
public Bar() : base(){
wrapper = subclassWrapper;
}
}
So each instance now needs to hold an extra reference, however I don't need to keep a function. The wrapper is kept within the base class so it is less fragmented.

C# Way to enforce all classes have a method of a given name

I am not sure if this even makes sense hence asking it widely.
Is it possible for enforce that a set of classes always implements a function with a given name. The method in each class might have different signature - but should have the same name. Some like below:
public class ClassOne {
public int GetSomething (int a, int b, out int c) { }
}
public class ClassTwo {
public int GetSomething ( int a, out string b) {}
}
I want anyone who writes ClassThree or ClassFour as part of this library to implement the GetSomething method. Is there a C# construct that allows one to enforce this?
Not looking at design review of this - just want to know if its possible at all without manually enforcing via code reviews.
You can't do that with out-of-the-box C#. C# has abstract classes and interfaces, but they require a specific signature for a method, not just a name.
You could get this working by creating code analyzers in Roslyn, where you check your code if it has the required method.
However, I don't think you should all this. I think you are making a design flaw here in requiring a method with a specific name, without forcing the arguments of it.
You could always implement a method similar to the Main method found in every C# application. It uses a string[] as parameter where you can put a number of variables in. In your case I would opt for an object[]. However, this design has its flaws too obviously.
What is the purpose of a class with method of unknown arguments. It is just illogical in terms of OOP. How are you going to call this method? If arguments are homogeneous then you could just do something like:
public interface IBaseInterface
{
public int GetSomething(Dictionary<string, object> args); // keys matter
}
or
public interface IBaseInterface
{
public int GetSomething(params object[] args); // order matters
}
In some cases Func<> / Action<> high-order functions may be useful.
If you provide a usage case, we would be able to make a more precise answer.
Show how you are going to call such method and I will try to show how to make it better.
Answering your question only from technical side, you could do the following:
public abstract class BaseClass
{
protected BaseClass()
{
if (this.GetType().GetMethod("GetSomething") == null)
throw new InvalidOperationException("BaseClass subclasses should implement 'GetSomething' method");
}
}
public class ClassOne : BaseClass {
public int GetSomething (int a, int b, out int c) { }
}
public class ClassTwo : BaseClass {
public int GetSomething (int a, out string b) {}
}
It will not guarantee this behavior at design-time, but will ensure that such methods exists at run-time.
Add an interface with the method you want.
Set classes inherit from this interace
interface ISampleInterface
{
void SampleMethod();
}
class ImplementationClass1 : ISampleInterface
{
// Explicit interface member implementation:
void ISampleInterface.SampleMethod()
{
// Method implementation.
}
}
How about encapsulating parameters in a "Criteria" object?
public interface IGettable
{
int GetSomething (Criteria crit);
}
public class Criteria
{
public CriteriaType type {get; set;};
public int a {get; set;};
public int b {get; set;};
...
public static Criteria ClassOneCriteria(int a, int b)
{
return new Criteria
{
type = CriteriaType.ClassOneCriteria,
a = a,
b = b
}
}
...
}
public enum CriteriaType
{
ClassOneCriteria,
ClassTwoCriteria
}
public class ClassOne : IGettable
{
public int GetSomething (Criteria crit)
{
if (crit.type != CriteriaType.ClassOneCriteria)
throw new Exception("Invalid criteria type for Class One");
...
}
}

every entity implement interface?

Currently, am working on architecture of application, I have many entities in my project i.e student teacher university, I was wondering about is it a good practice that all entity must implement interface. This will help me in dependency injection? What is the best practice from architecture point of view.
public interface IMyEntity
{
//an empty interface
}
public class Student:IMyEntity
{
}
public class Teacher:IMyEntity
{
}
//hi I can deal with every object which implement IMyEntity
void Display(IMyEntity entity) //this function can be in some class
{
// if IMyEntity is teacher behave like a teacher
// if IMyEntity is student behave like sutdent
}
I know interface is a contract, but from architecture point of view it is best practice? I know my IMyEntity interface is empty.
Not necessarily. If in this case Student and Teacher have some common functionality then a shared interface would be one approach to take.
public void Display(IUniPerson person)
{
var name = person.Name; // Everyone, student or teacher, has a name
...
}
However, the example you give seems to suggest that this is not the case, and the Display method will attempt to treat the passed in instance of IMyEntity differently depending on it's type. In that case, you may be better with 2 Display methods with different parameters.
public void Display(ITeacher teacher) { // teacher processing }
public void Display(IStudent student) { // student processing }
tl:dr version: implement an interface across multiple classes if it makes sense for those classes to implement related methods and functions, rather than just as a blanket rule.
I think that decoupling 2 or more classes is a good taste in terms of developing and it really helps maintaining the code in a long run.
Consider the follow scenario:
static void Main(string[] args)
{
var objA = new A();
var objB = new B(objA);
}
public class A {}
public class B
{
public B(A obj)
{
//Logic Here
}
}
The problem with this code it's that it's strongly coupled, class B needs class A to be instanced and do it's business.
This is not a problem if you are sure that B is never going to have some drammatic change.
Now if we want to decouple it we can make a first improvement implementing an interface like
static void Main(string[] args)
{
var objA = new A();
var objB = new B(objA);
}
public interface IA()
{
//TODO
}
public class A : IA {}
public class B
{
public B(IA obj)
{
//Logic Here
}
}
It looks quite better what we still have a couplation problem in the Main, so at this point we will have to implement a Dependency Injection with a IOC like Ninject, and our code will be like to something like:
static void Main(string[] args)
{
var objB = new B();
}
public interface IA()
{
//TODO
}
public class A : IA {}
public class B
{
public B(IA obj)
{
//Logic Here
}
}
Yes, that looks good. We have completely removed the couplation problem and it will be quite easy if in the future we just need to take A, delete it and replace it wich something new more cool.
Obviously overkilling it's a bad practice and I belive DI must be used only after carefuly planning to avoid useless implementations.
For example if I have a class C which has some basic operations, and I am sure that it will never change or have some drammatic need to update i can avoid DI.
So do you have to implement interfaces on every model in your project?
Well I don't think each model in your project needs to implements an interface or DI, just think about it and see where it can be useful and where it's just overkilling.
Looking at how .NET solved this, you can see some ambiguity.
For instance for every object has a function where you can ask for a string representation of the object: ToString(), even though for a string representation might not be a meaningful thing for a lot of classes
On the other hand, although it would be a useful function for every object to make a clone of itself they decided not to let every class implement ICloneable.
Whether it is wise for you to have (almost every) objects of your application a common interface depends on what you will do with this interface and the advantage of all objects implementing such an interface versus the burden of being obliged to implement the interface.
For example, if the entities you are talking about are database records, then it is very likely that every class will have some kind of ID. You could consider giving every class an interface with one get property that returns the value of the ID of the record.
public interface IID
{
long ID {get;}
}
The advantage are multifold:
You encourage every designer of database classes to implement the same type of primary key (in this case a long), and the same property name
Advantage: it is easier to spot the ID of a record
Advantage: it is easier to change the type of the ID
Advantage: you know if you have a database record, you know some of the functions the record must have, without really knowing the type of the record.
Even if the designer needs a different type, or different name, he can still create a special function to implement the interface:
public class Person : IID
{
public int ID {get; set;}
IID:ID {get {return this.ID;} }
}
However, I suggest not to force interfaces to object for which it is not natural to have them. This has the advantage that you can't use these strange functions for object that have no real usage for them.
For example, most classes that represent some ordered numerical value have some notion of addition. Not only for integers and real numbers, but also for classes that represent a time span: 4 days and 23 hours + 1 day and 7 ours = 6 days and 6 hours. So for a time span addition is a useful interface
However, for a date, addition is not meaningful: 4th of july + 14 juillet = ?
So: Yes, implement interfaces for items that are natural to them. They force common naming and enable reuse. No, don't implement them for items that do not have a natural meaning for the functions.
Yes do it like this, it is the best practise. This gives you the advantage of polymorphism. You should do it in better way in current context is not good, because Student is not a Teacher. If you want to share common interface you should define it as: IUniversityMember. Here an example for your case which I think will make it clear.
public interface IUniversityMember
{
//... here common fields between `Teacher` and `Student`
string Name{ get; set;}
string Gender { get; set;}
}
//after that
public interface IStudent
{
int GetGPA();
int CreditsToPass {get; private set;}
}
public interface ITeacher
{
int WorkedHours {get; set;}
decimal PayPerHour {get; private set;}
}
public class BiologicalStudent: IUniversityMember, IStudent
{
public int CreditsToPast {get; private set;}
public BiologicalStudent ()
{
CreditsToPast = 5;
}
//stuff
public int GetGPA()
{
return 3;
}
}
public class MathStudent: IUniversityMember, IStudent
{
public int CreditsToPast {get; private set;}
public BiologicalStudent ()
{
CreditsToPast = 9;
}
public int GetGPA()
{
return 2;
}
}
public class BiologicalTeacher: IUniversityMember, ITeacher
{
public int WorkedHours { get; set;}
public decimal PayPerHour {get; private set;}
public MathTeacher()
{
PayPerHour = 8;
}
}
public class MathTeacher: IUniversityMember, ITeacher
{
public int WorkedHours { get; set;}
public decimal PayPerHour {get; private set;}
public MathTeacher()
{
PayPerHour = 10;
}
}
//Now if you have a university class
public class OxfordUniversity:IUniversity //can inherit interface too
{
public int MinGAPForSchollarship {get; private set;}
public OxfordUniversity()
{
MinGAPForSchollarship = 3;
}
public decimal PaySallary(ITeacher teacher)
{
return teacher.WorkedHours*teacher.PayPerHour;
}
public bool CheckForSchollarship(IStudent student)
{
int gpa = student.GetGPA();
//do some checks
if(gpa >= MinGAPForSchollarship)
return true;
return false;
}
}

Dynamically Compose a Class in C#

Is it possible to dynamically compose a class from the methods contained in other Classes?
For instance. Class A, B and C have public methods named such that they can be identified easily. They need to be extracted and added to Class D. Class D, which then contains all of the implementation logic can be passed further into a system which only accepts a single instance of Class D and dynamically binds these methods to other functions.
To be clear, this is not inheritance I'm looking for. I'm literally stating that methods with different names need to be stuffed into one class. The system I pass it into understands these naming conventions and dynamically binds them (it's a black box to me).
I am going down the path of extracting the methods from A, B, and C, dynamically combining them with the source of Class D in memory and compiling them into a new Class D and then creating an instance of D and passing it forward.
public class A{ public void EXPORT_A_DoSomething(){} }
public class B{ public void EXPORT_B_DoSomethingElse(){}}
public class C{ public void EXPORT_C_DoAnything(){}}
//should become
public class D{
public void EXPORT_A_DoSomething(){}
public void EXPORT_B_DoSomethingElse(){}
public void EXPORT_C_DoAnything(){}
}
Is there a way to extract the MethodInfos from class A, B and C and somehow directly attach them to Class D? If so how?
I would consider using the C# Class compiler. From what I can remember you can build code that is in a string and you can get an assembly as output. This then enables you to invoke methods through reflection.
There is an example on the MSDN link I have specified but I will mock one up for here once I find my project.
You won't be able to export just the methods. The methods can't really be separated from the class that they are in. (they need access to all of the member fields/properites including inherited).
I think the only thing you can do is emit a interface implementation. (even though you say it's not what you need, I don't see a way around needing the private state for those objects)
You can make a single interface which contains only the methods you need, and provide a class that supports it which contains an instance of each type of object.
public class A{ public void DoSomething(){} }
public class B{ public void DoSomethingElse(){}}
public class C{ public void DoAnything(){}}
public interface ID
{
void A_DoSomething();
void B_DoSomethingElse();
void C_DoAnything();
}
public class D : ID
{
private A a;
private B b;
private C c;
public D(A a,B b, C c) { this.a=a;this.b=b;this.c=c; }
public void A_DoSomething(){ a.DoSomething();}
public void B_DoSomethingElse(){ b.DoSomethingElse();}
public void C_DoAnything(){ c.DoSomething();
}
If you need to generate this dynamically, look into Reflection.Emit. It'll be some business about how you've got to create a new assembly, and then load it dynamically into the AppDomain. I'd try to avoid that if you can.
It should actually be possible using something called "Mixins" and proxy generators. Take a look at Castle.DynamicProxy's tutorial: Mixins
Another solution is to define the class get and set accessors for the function as an interface, and declare the functions you are interested in.
interface iA
{
public int a { get; set; }
}
interface iB
{
public int b { get; set; }
}
interface iAB : iA, iB
{
}
class MyClass : iA, iB
{
public int b { get; set; }
public int a { get; set; }
}
static class MyClassExtender
{
static public int Foo(this iAB ab)
{
int c = ab.a + ab.b;
ab.a = c;
return c;
}
static public int FooA(this iA a)
{
int c = ab.a + 1;
ab.a = c;
return c;
}
static public int FooB(this iB b)
{
int c = ab.b + 1;
ab.a = c;
return c;
}
}
So now "MyClass" can use Foo, FooA, and FooB as public methods.
Have you considered simply using a hash or list of delegates in you D class that point to the methods on the other classes? Alternatively, use a dynamic object (google ExpandoObject).

How to inherit a static property with a unique value for each subclass?

I have a series of objects, lets call them buildings, that each share certain properties that are static for that building, but different for each building, such as price. I assumed that the best way to implement this was to create an abstract superclass with the shared price attribute and set the values in each subclass, but I cannot figure out how to get this to work. Here is an example of something I have tried:
using System;
public abstract class Buildings
{
internal static int price;
internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
public Walls()
{
price = 200;
turnsToMake = 5;
}
}
This works fine for construction, but if I want to check the price before creating it (to check if the player has enough money) then it just returns a null value. I'm sure that it is is a super simple fix, but I can't figure it out. Any help?
There is a "patchy" yet simple solution that's worth to consider. If you define your base class as a Generic class, and in deriving classes set T as the class itself, It will work.
This happens because .NET statically defines a new type for each new definition.
For example:
class Base<T>
{
public static int Counter { get; set; }
public Base()
{
}
}
class DerivedA : Base<DerivedA>
{
public DerivedA()
{
}
}
class DerivedB : Base<DerivedB>
{
public DerivedB()
{
}
}
class Program
{
static void Main(string[] args)
{
DerivedA.Counter = 4;
DerivedB.Counter = 7;
Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
Console.ReadLine();
}
}
Don't use static. Static says that all instances of Building have the same value. A derived class will not inherit its own copy of the statics; but would always modify the base class statics. In your design there would only be one value for price and turnsToMake.
This should work for you:
public abstract class Buildings
{
internal int price;
internal int turnsToMake;
}
However, most people don't like using fields these days and prefer properties.
public abstract class Buildings
{
internal int Price { get; set; }
internal int TurnsToMake { get; set; }
}
I want to check the price before creating it […]
I suppose that's how you got to static fields; however, static and virtual behaviour cannot be combined. That is, you would have to re-declare your static fields for each subclass. Otherwise, all your subclasses share the exact same fields and overwrite each others' values.
Another solution would be to use the Lazy<T, TMetadata> type from the .NET (4 or higher) framework class library:
public class Cost
{
public int Price { get; set; }
public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
valueFactory: () => new Walls(),
metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
var buildings = lazyBuildings.Value;
}
That is, the metadata (.Metadata) now resides outside of the actual types (Buildings, Walls) and can be used to decide whether you actually want to build an instance ( .Value) of it.
(Thanks to polymorphism, you can have a whole collection of such "lazy factories" and find a building type to instantiate based on the metadata of each factory.)
Building on Uri Abramson's answer above:
If you need to access the static property from within the Base class, use reflection to get the value from T. Also, you can enforce that Base must be inherited using T of the derived type.
e.g.
class Base<T> where T : Base <T> {
static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
{
return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
}
static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}
If you have a better way to do this, please post.
Not as easy for the inheritor, but workable...
public abstract class BaseType
{
public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
protected static contentType _inheritedTypeContent;
public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}

Categories

Resources