Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I got a C# project where I need to have a base class and two sub classes and I want the sub classes to be private to the base classes. This is how it looks like:
public class MyBaseClass
{
public void doMyWork()
{
doSubClass1();
doSubClass2();
}
}
private class MySubClass1
{
public void doSubClass1()
{
//Do stuff
}
}
private class MySubClass2
{
public void doSubClass2()
{
//Do stuff
}
}
How i can i get this to work?
Does it hurt if the classes themselves are not-so-private but still wrapped in your base & unaccessible outside?
public class MyBaseClass
{
private readonly MySubClass1 _sub1 = new MySubClass1();
private readonly MySubClass2 _sub2 = new MySubClass2();
public void DoMyWork()
{
_sub1.DoSubClass1();
_sub2.DoSubClass2();
}
}
public class MySubClass1
{
public void DoSubClass1() { /* Do stuff */ }
}
public class MySubClass2
{
public void DoSubClass2() { /* Do stuff */ }
}
If this is not good enough and you need those in separate files, as you stated, then you can use partial classes, like so.
Class1.cs file
public partial class MyBaseClass
{
public void DoMyWork()
{
(new MySubClass1()).DoSubClass1();
(new MySubClass2()).DoSubClass2();
}
}
Class2.cs file
public partial class MyBaseClass
{
private class MySubClass1
{
public void DoSubClass1() { /* Do stuff */ }
}
}
Class3.cs file
public partial class MyBaseClass
{
private class MySubClass2
{
public void DoSubClass2() { /* Do stuff */ }
}
}
But still it's not quite clear what you are trying to achieve here.
If you put your subclasses inside of the base class, the base class can access them. To use your example, it would be like this:
public class MyBaseClass
{
public void doMyWork()
{
new MySubClass1().doSubClass1();
new MySubClass2().doSubClass2();
}
private class MySubClass1
{
public void doSubClass1()
{
//Do stuff
}
}
private class MySubClass2
{
public void doSubClass2()
{
//Do stuff
}
}
}
Note that all I did was move the last } to the bottom.
Related
consider the following game code:
public class Player : MonoBehaviour {
public void UseItem(Item item) {
item.Use(this);
}
public void GetDrunk() {}
}
public class Item {
public WhatInterface[] itemUsages;
public void Use(Player player) {
foreach(var usage in itemUsages) {
usage.Execute(new ItemUsageArgs {itemUser = player, itemUsed = this})
}
}
}
public class GameManager : MonoBehaviour {
public Player mainCharacter;
public Item beer = new Item {itemUsages = new [] {
new TestConsole(),
new DamageFromItem (),
new DrunkFromITem ()
}}
private void Start() {
mainCharacter.Use(beer);
}
}
public class TestConsole : WhatInterface {
public void Execute(BaseArgs args) {
Debug.Log("function call executed");
}
}
public class DamageFromItem : WhatInterface {
public void Execute(ItemUsageArgs args) {
Debug.Log(args.itemUser + " take damage from " + args.itemUsed);
}
}
public class DrunkFromITem : WhatInterface {
public void Execute(ItemUsageArgs args) {
args.itemUser.GetDrunk();
}
}
public class BaseArgs {}
public class ItemUsageArgs : BaseArgs {
public Player itemUser;
public Item itemUsed;
}
so how to create interface type code that is suited for itemUsages?
Or do I wrongly create the design for this context?
Basically I'm trying strategy pattern so that item usages could be vary for every kind of item.
Things I tried, creating IItemUsage interface:
public interface IItemUsage {
void Execute(ItemUsageArgs args);
// but then anything that needs to implement this interface must use this method, even though it only needs BaseArgs.
// TestConsole class must conform to Execute(ItemUsageArgs) signature..
}
public class TestConsole : IItemUsage {
public void Execute(BaseArgs args) {
Debug.Log("function call executed");
}
// this won't compile
}
Assuming this is all of your code, you can make IItemUsage generic, and contravairant on the generic parameter.
public interface IItemUsage<in T> where T: BaseArgs {
void Execute(T args);
}
Have TestConsole implement IItemUsage<BaseArgs> and the other two classes implement IItemUsage<ItemUsageArgs>.
Now you can put instances of all three classes into an IItemUsage<ItemUsageArgs>[]:
IItemUsage<ItemUsageArgs>[] arr = new IItemUsage<ItemUsageArgs>[] {
new TestConsole(), new DamageFromItem(), new DrunkFromITem()
};
If you want to implement interface with some method, which has input arguments, that can be different types, you must define base argument class or use interface parameter instead.
For example:
public interface IItemUsage
{
void Execute(IItemUsageArgs args);
}
public interface IItemUsageArgs
{
//place public part of all ItemUsageArgs
}
public class ItemUsageArgs1 : IItemUsageArgs
{
}
public class ItemUsageArgs2 : IItemUsageArgs
{
}
public class ItemUsage1 :IItemUsage
{
public void Execute(ItemUsageArgs1 args)
{
//do you need
}
void IItemUsage.Execute(IItemUsageArgs args)
{
Execute(args as ItemUsageArgs1);
}
}
public class ItemUsage2 : IItemUsage
{
public void Execute(ItemUsageArgs2 args)
{
//do you need
}
void IItemUsage.Execute(IItemUsageArgs args)
{
Execute(args as ItemUsageArgs2);
}
}
I have a abstract base class, starting a timer which is common to all derived class,
public abstract class BaseClass
{
public virtual void Start() { _timer.Start(); }
}
Now I need to load different JSON configuration files for each derived class and create the file,
public class DerivedClass1 : BaseClass
{
private readonly List<config> configs = new List<config>();
public DerivedClass1()
{
configs = JsonSettings.GetConfigurations(#"./Configurations/1.json");
}
public override void Start()
{
base.Start();
foreach (var configuration in configs)
{
JsonSettings.CreateConfigFile(configuration);
}
}
}
public class DerivedClass2 : BaseClass
{
private readonly List<config> configs = new List<config>();
public DerivedClass2()
{
configs = JsonSettings.GetConfigurations(#"./Configurations/2.json");
}
public override void Start()
{
base.Start();
foreach (var configuration in configs)
{
JsonSettings.CreateConfigFile(configuration);
}
}
}
As I see there are lots of codes are duplicated in various derived class.
Can I move these piece of code as well as abstract base class or is there another way?
I think you could simplify your code to this:
public abstract class BaseClass
{
protected virtual List<config> configs { get; set; } = new List<config>();
public virtual void Start()
{
_timer.Start();
foreach (var configuration in configs)
{
JsonSettings.CreateConfigFile(configuration);
}
}
}
public class DerivedClass1 : BaseClass
{
public DerivedClass1()
{
configs = JsonSettings.GetConfigurations(#"./Configurations/1.json");
}
}
public class DerivedClass2 : BaseClass
{
public DerivedClass2()
{
configs = JsonSettings.GetConfigurations(#"./Configurations/2.json");
}
}
public interface BaseClass
{
void Start();
}
public interface IBaseClassUtil
{
void Start();
void setConfigs(List<config> configs);
}
public class BaseClassUtil : IBaseClassUtil
{
System.Timers.Timer _timer;
public List<config> _configs { get; set; } = new List<config>();
public void Start()
{
_timer.Start();
foreach (var configuration in _configs)
{
JsonSettings.CreateConfigFile(configuration);
}
}
public void setConfigs(List<config> configs)
{
_configs = configs;
}
}
public class DerivedClass1 : BaseClass
{
private IBaseClassUtil _baseUtility;
public DerivedClass1(IBaseClassUtil baseUtility)
{
_baseUtility = baseUtility;
_baseUtility.setConfigs( JsonSettings.GetConfigurations(#"./Configurations/1.json"));
}
public void Start()
{
_baseUtility.Start();
}
}
public class DerivedClass2 : BaseClass
{
private IBaseClassUtil _baseUtility;
public DerivedClass2(IBaseClassUtil baseUtility)
{
_baseUtility = baseUtility;
_baseUtility.setConfigs(JsonSettings.GetConfigurations(#"./Configurations/2.json"));
}
public void Start()
{
_baseUtility.Start();
}
}
This might be oveer engineered. Or might not suit ur current requirement.
Advantages would be
In future if you want u want to have different implementation for IBaseClassUtil it will be easier
And huge advantage would be this code is testable
If the classes differ by nothing but the configuration path, then you can have only one derived class that takes the path as a parameter in its ctor.
public DerivedClass(string configurationPath)
{
configs = JsonSettings.GetConfigurations(configurationPath);
}
Put please note that a decision on including inheritance in your architecture is not about code duplication, and by not giving us any information on the functions or even names of the classes (BaseClass and DerivedClass mean nothing. What do they represent? What's their function? Why are they related?) you give us no way of really helping you with your design.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Lets say that i have a "Timer" class with a method that every 1 second is called, and it calls another method in the class "Gear":
public class Timer
{
public void OnTick()
{
Gear.Update();
}
}
public class Gear
{
public static void Update() { }
}
This kinda works, but it's only called on the base class.
The method "Update" should be called in all the childrens of "Gear":
e.g:
public class AnotherClass : Gear
{
public override void Update() { // do stuff }
}
public class YetAnotherClass : Gear
{
public override void Update() { // do stuff }
}
public class AndAnotherClass : Gear
{
public override void Update() { // do stuff }
}
How can i do this?
In order for the code to work the way you want, you'd need to do something like this (I would worry about a memory leak):
public abstract class Gear
{
readonly static List<Gear> gears = new List<Gear>();
public Gear()
{
gears.Add(this);
}
public static void Update()
{
foreach (var gear in gears)
gear._Update();
}
protected abstract void _Update();
}
public sealed class Gear1 : Gear
{
protected override void _Update()
{
//do stuff
}
}
public sealed class Gear2 : Gear
{
protected override void _Update()
{
//do stuff
}
}
public sealed class Gear3 : Gear
{
protected override void _Update()
{
//do stuff
}
}
public static void Main(string[] args)
{
var timer =
new Timer(o => Gear.Update(), null, 0, SOME_INTERVAL);
}
However, you might be better off by defining the base case thusly:
public abstract class Gear
{
public abstract void Update();
}
And then define a collection class:
public sealed class GearCollection : List<Gear>
{
public void Update()
{
foreach (var gear in this)
gear.Update();
}
}
And then
public static void Main(string[] args)
{
var gears = new GearCollection();
//add gear instancs to gears
var timer = new Timer(o => gears.Update(), null, 0, SOME_INTERVAL);
}
This is a really simple structure question, but i don't know what is the best way to do this in C#.
I need a "base" class or something to allow me load diferent "levels" in the "level" object, and changing the name I can swith the class what I want to use.
Now i'm using a abstract class and instance of the childrens in this way:
using UnityEngine;
using System;
public class Level : MonoBehaviour {
public levelClass level;
public void initLevel(string className) {
Type t = Type.GetType(className);
level = (levelClass)Activator.CreateInstance(t, new object[] { });
level.Start();
}
void Start () {
Debug.Log("Levels: Start");
initLevel("worldTwo");
}
void Update () {
level.Update();
}
}
public abstract class levelClass {
public abstract void Start();
public abstract void Update();
}
public class worldOne : levelClass {
public override void Start() {
Debug.Log("worldOne: Start");
}
public override void Update() {
Debug.Log("worldOne: Update");
}
}
public class worldTwo : levelClass
{
public override void Start()
{
Debug.Log("worldTwo: Start!");
}
public override void Update()
{
Debug.Log("worldTwo: Update!");
}
}
But I think exists better ways to do, like store all classes in a list and call it or something similar. The part i don't like nothing is have some classes public in this file (I know i can split in other files, i'm trying to think only in a way to do this better)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a class with some functions. The functions can be categorize in "NameSpace".
I search a way to organize each function into somekind of namespace into my class.
It was suggested to me to change my approach. Using Interface instead of inheritance.
Here some sample for be understand
public class Class1
{
public string A = "A";
public string B = "B";
public int one = 1;
public int two = 2;
public Printer globalPrinter;
}
public class Class10 : Class1
{
public class Letter
{
public void FunctionA()
{
globalPrinter.print(A);
}
public void FunctionB()
{
globalPrinter.print(B);
}
}
public class Number
{
public void Function1()
{
globalPrinter.print(one);
}
public void Function2()
{
globalPrinter.print(two);
}
}
}
public class ClassX : Class10
{
public ClassX()
{
Letter.FunctionA();
Letter.FunctionB();
Number.Function1();
Number.Function2();
}
}
var c10 = new ClassX();
This code doesn't work. You could look, at the end of the sample, you'll see
Letter.FunctionA();
Letter.FunctionB();
Number.Function1();
Number.Function2();
I could simply put FunctionA and FunctionB inside Class10. But if there's 100 functions. It could be more interesting to split function into Categories.
Let me see your approach of the problem.
I added some item for helping the categorization.
Answer Full Code
public class Class1
{
public string A = "A";
public string B = "B";
public int one = 1;
public int two = 2;
public void globalPrinter(object t)
{
}
}
public class Class10 : Class1
{
public class Letter
{
readonly Class10 parent;
public Letter(Class10 parent)
{
this.parent = parent;
}
public void FunctionA()
{
parent.globalPrinter(parent.A);
}
public void FunctionB()
{
parent.globalPrinter(parent.B);
}
}
public class Number
{
readonly Class10 parent;
public Number(Class10 parent)
{
this.parent = parent;
}
public void Function1()
{
parent.globalPrinter(parent.one);
}
public void Function2()
{
parent.globalPrinter(parent.two);
}
}
}
public class ClassX : Class10
{
public ClassX()
{
new Letter(this).FunctionA();
new Letter(this).FunctionB();
new Number(this).Function1();
new Number(this).Function2();
}
}
ClassX c10 = new ClassX();
The problem is that a sub class like Class10.Letter is not part of the inheritance hierarchy that its parent class Class10 is part of.
So, Class10.Letter does not inherit from Class1, only Class10 inherits from Class1, so Class10.Letter needs an instance of Class1 or Class10 so it can access globalPrinter
public class Class10: Class1 {
public class Letter {
readonly Class10 parent;
public Letter(Class10 parent) {
this.parent = parent;
}
public void FunctionA() {
parent.globalPrinter.print(parent.A);
}
}
}
Also ClassX inherits from Class10 so it has access to Class10 functions, but it does not inherit from Class10.Letter, soClassX needs an instance of Letter if it is calling non-static functions:
public ClassX() {
new Letter(this).FunctionA();
...