Create new instance of private class in another private class - c#

Is it possible to create an instance of a private class in another private class? (Not counting within the main() program.)
And also, is it possible for a method in a private class to return a private type object?
This question came because I was following Scott Allen from PluralSight on C# Fundamentals With C#5. And on lesson 2 about classes and objects, he has a code example like this:
public GradeStatistics ComputeStatistics()
{
GradeStatistics stats = new GradeStatistics();
...
...
}
with GradeStatistics defined in a separate class file like:
class GradeStatisticss
{
}
Inlined comment: I am not talking about nested classes. What I meant is, you have two classes (separate files) and I am wondering if one class can create an instance of another class (knowing they are both private).
Edited with examples:
private class Example1
{
}
private class Example2
{
public Example1 DoSomeComputation()
{
return new Example1();
}
}
private class Example3
{
Example1 ex1 = new Example1();
}
Is Example3 able to create ex1? Can Example2 return a new instance of Example1?

Is it possible to create an instance of a private class in another private class?
Only if the private class for which you want to create an instance is declared inside the private class that wants to create the instance. If they are not nested, it's not possible.
Is it possible for a method in a private class to return a private type object?
Yes, it can.
Here's some code showing everything together:
public class Tester {
private class ThePrivateCreator {
private class TheOtherPrivateClass {
}
public Object createObject() {
return new TheOtherPrivateClass();
}
}
public void canWeDoThis() {
ThePrivateCreator c = new ThePrivateCreator();
Console.WriteLine(c.createObject());
}
}
class Program
{
public static void Main(string[] args) {
Tester t = new Tester();
t.canWeDoThis();
}
}

No. A private class cannot be accessed by another class in a different file. The reason why is that the modifier private is meant to encapsulate the data or method inside of that class. You should use the public or internal modifier if you want to access a class from a different class that is not nested. If it is nested, you can also use the protected modifier.

Not sure exactly what you had in mind, but here's one possible example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication26
{
class Program
{
static void Main(string[] args)
{
private1 p1 = new private1();
private2 p2 = p1.foo();
Console.WriteLine(p2.Value);
Console.ReadLine();
}
private class private1
{
public private2 foo()
{
private2 p2 = new private2("I was created inside a different private class!");
return p2;
}
}
private class private2
{
private string _value;
public string Value
{
get { return _value; }
}
public private2(string value)
{
this._value = value;
}
}
}
}

Related

Is there a way to organize my functions into subclasses or some form of nested container?

So i'm trying to organize my functions into nested classes so i can call them like: "Player.Trigger_Functions.TakeDamage()" rather than calling it as such: "Player.TakeDamage()". I suppose it is a less efficient way to call the functions the way I'm suggesting but it would help separate the functions into distinct categories while remaining on the same file.
Here is some test code but i can't get it to compile online to see if it works.
(some of the functions need to be able to interact with each-other despite being in separate containers which i think is a problem)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Program
{
public class meme{
public int thicc = 0;
public oof nest1 = new oof();
public watermelone nest2 = new watermelone();
public class oof : meme
{
public void here(){
thicc++;
}
public void call(){
nest2.here();
System.Console.WriteLine("oof" + thicc);
}
}
public class watermelone : meme
{
public void here(){
thicc++;
}
public void call(){
nest1.here();
System.Console.WriteLine("watermelone" + thicc);
}
}
}
public static void Main(){
meme me = new meme();
me.nest1.call();//adding 1
me.nest2.call();//adding 1
System.Console.WriteLine("here is the current thicc value of the me class:" + me.thicc);
}
}
Ok yeah so this code wouldn't work at all, i didn't put that much thought into it but you get the idea of what i'm trying to accomplish.
You can use interfaces to break up the functionality of your class into related groups.
From this:
class Person
{
void sayHello() { }
void sayGoodbye() { }
void walkForward() { }
void walkBackward() { }
}
Refactor into this:
interface ISpeak
{
void sayHello();
void sayGoodbye();
}
interface IWalk
{
void walkForward();
void walkBackward();
}
class Person : ISpeak, IWalk
{
void ISpeak.sayHello() { }
void ISpeak.sayGoodbye() { }
void IWalk.walkForward() { }
void IWalk.walkBackward() { }
}
class Program
{
static void Main(string[] args)
{
Person person = new Person();
IWalk walk = person;
ISpeak speak = person;
speak.sayHello();
walk.walkForward();
}
}

How to allow a different singleton class to be instantiated by passing different parameters into the constructor

I have a class in my project and I want to instantiate it only once by passing a specific parameter via the constructor, but when I pass different parameter it should instantiate a new one. How I can achieve this with the singleton design pattern? Or can you suggest another design pattern if it can't be achieved with a singleton?
class Program
{
static void Main()
{
SiteStructure s = SiteStructure.Instance;
}
}
public sealed class SiteStructure
{
static readonly SiteStructure _instance = new SiteStructure();
public static SiteStructure Instance
{
get
{
return _instance;
}
}
SiteStructure()
{
// Initialize.
}
}
You have to modify the way the _instance variable is initialised, making use of a function that accepts the parameter value that you want to pass in. Also, the _instance variable can no longer be readonly as it needs to be initialised inside of the new function.
[TestMethod]
public void CreateSingletonInstance()
{
SiteStructure s = SiteStructure.GetInstance("Abc123");
Debug.Print(s.Parameter); // outputs Abc123
SiteStructure s2 = SiteStructure.GetInstance("Is it really a singleton?");
Debug.Print(s2.Parameter); // outputs Is it really a singleton?
SiteStructure s3 = SiteStructure.GetInstance("Abc123");
Debug.Print(s3.Parameter); // outputs Abc123
Assert.AreNotEqual(s, s2); // Check to make sure they are different instances
Assert.AreEqual(s, s3); // Check to make sure they are the same instance
}
public sealed class SiteStructure
{
static Dictionary<string, SiteStructure> _siteStructures = new Dictionary<string, SiteStructure>();
static object _instance_Lock = new object();
public static SiteStructure GetInstance(string parameter)
{
if (!_siteStructures.ContainsKey(parameter))
{
lock (_instance_Lock)
{
if (!_siteStructures.ContainsKey(parameter))
{
_siteStructures.Add(parameter, new SiteStructure(parameter));
}
}
}
return _siteStructures[parameter];
}
private SiteStructure(string parameter)
{
// Initialize.
Parameter = parameter;
}
public string Parameter { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var g = SiteStructure.Instance(4);
}
}
public sealed class SiteStructure {
public static SiteStructure Instance()
{ return new SiteStructure();
}
public static SiteStructure Instance (int x)
{ return new SiteStructure (x);
}
SiteStructure() { }
SiteStructure(int x) { Console.WriteLine("Hello"); }
}
}

Access static object from other instance

I have a Program class which has:
private static ClientBase objClientBase = new ClientBase(new List<RecordType> { RecordType.none }, ModuleType.Monitor);
static void Main(string[] args)
{
objClientBase.Connect(); //IRRELEVANT
objQueueMon = new Main(); //<-INSIDE THIS IS WHERE I WANT TO ACCESS objClientBase
objClientBase.MainModuleThreadManualResetEvent.WaitOne(); //IRRELEVANT
}
This Progam creates a Main class instance as you see:
objQueueMon = new Main();
Notice that they are separated in different files, but the Main class instance is created inside the Program class.
Inside my Program class I want to access that objClientBase.
Do I have to create a constructor method and pass it or make a public access to it?
So what I want to achieve is, inside the Main class, do a objClientBase.FUNCTION
You can do exactly what you just said:
public class Main {
private ClientBase _caller;
public Main (ClientBase caller) {
_caller = caller;
}
}
Or, you can set it later
public class Main {
private ClientBase _caller;
public Main () {
}
// only your assembly sets it
internal SetClientBase(ClientBase cb) {
_caller = cb;
}
// but anyone gets it
// Now you can let some client execute "Function"
public ClientBase Caller {
{return _caller;}
}
}
Just an example
Change the constructor of your Main class to accept a ClientBase object, like this:
public class Main
{
private ClientBase _clientBase;
public Main(ClientBase clientBase)
{
_clientBase = clientBase;
}
public void SomeMethod()
{
// Use ClientBase.FUNCTION here
_clientBase.FUNCTION();
}
}

c#: Calling common method of stored references to class objects from object[] array

Is using a switch on object types really the main way of calling a common function of stored references to class objects? It doesn't have to be a 'object' value type.
using System;
public class MainClass { public void Main() { print "hello world"; } }
public class SubClassOne : MainClass { }
public class SubClassTwo : MainClass { }
public class Storer
{
public void Main() {
object[] objects = new object[2];
objects[0] = new SubClassOne();
objects[1] = new SubClassTwo();
for(i=0;i<2;i++)
{
switch(objects[i].GetType().ToString())
{
case: "SubClassOne":
SubClassOne subclass = objects[i];
subclass.Main();
break;
case: "SubClassTwo":
SubClassTwo subclass = objects[i];
subclass.Main(); //Could probably call after the switch
break;
}
}
}
}
Note: Code not parsed, so there may be serious errors.
"Stringly" typed object oriented code is such a bad idea. You (almost) never need to know the type of an object via a string.
Changing your "print" to Console.WriteLine and main to this works fine
MainClass[] stuff = new MainClass[2];
stuff[0] = new SubClassOne();
stuff[1] = new SubClassTwo();
foreach(var item in stuff)
{
item.Main();
}
If the problem is you are determined to use an array of object, AlexH has answered.
In that case, I suggest to use as keyword to perform a safe cast operation :
using System;
public class MainClass { public void Main() { print "hello world"; } }
public class SubClassOne : MainClass { }
public class SubClassTwo : MainClass { }
public class Storer
{
public void Main() {
object[] objects = new object[2];
objects[0] = new SubClassOne();
objects[1] = new SubClassTwo();
for(i=0;i<2;i++)
{
var myMainClass = objects[i] as MainClass;
if (myMainClass != null)
{
myMainClass.Main();
}
}
}
}
As wudzik said it should be even better to declare objects as a MainClass array
There are many ways of solving this in a nice way, depends on:
If you know types and there are not too much of them:
Use LINQ OfType<>(). For more details see MSDN
foreach (var item in objects.OfType<SubClassOne>())
{
item.Main();
}
foreach (var item in objects.OfType<SubClassTwo>())
{
item.Main();
}
If there are many types, just introduce common interface
interface ISharedApi
{
void Main();
}
class SubClassOne : ISharedApi
class SubClassTwo : ISharedApi
And implement this/mark each type by it, then you just need single loop:
var objects = new List<ISharedApi>();
objects.Add(new SubClassOne());
objects.Add(new SubClassTwo());
foreach (var item in objects)
{
item.Main();
}
You should implement a more object oriented solution. Instead of creating an array consisting of objects you should make MainClass abstract and define an abstract method Main. After that you should implement Main in you sublclasses.
In this way you can exchange your code to:
using System;
public abstract class MainClass { public abstract void Main(); }
public class SubClassOne : MainClass {
public override void Main() { print "SubClassOne, hello world"; }
}
public class SubClassTwo : MainClass {
public override void Main() { print "SubClassTwo, hello world"; }
}
public class Storer
{
public void Main() {
MainClass[] objects = new MainClass[2];
objects[0] = new SubClassOne();
objects[1] = new SubClassTwo();
foreach(MainClass mc in objects)
{
mc.Main();
}
}
}

How can I make one class solely responsible for creating and providing access to another class

This is how I understand I can implement the singleton pattern in C#:
public class ChesneyHawkes{
private static ChesneyHawkes _instance = new ChesneyHawkes();
public ChesneyHawkes Instance {get{return _instance;}}
private ChesneyHawkes()
{
}
}
What if I want to provide a single instance of an object, so that there can only ever be one, make the access to it public, but only allow it to be created or replaced by another singleton.
// The PuppetMaster should be the only class that
// can create the only existing Puppet instance.
public class PuppetMaster{
private static PuppetMaster_instance = new PuppetMaster();
public static PuppetMaster Instance {get{return _instance;}}
// Like a singleton but can be replaced at the whim of PuppetMaster.Instance
public static Puppet PuppetInstance {get {return Puppet;}}
private PuppetMaster()
{
}
public class Puppet{
// Please excuse the pseudo-access-modifier
puppetmasteronly Puppet(){
}
}
}
// To be accessed like so.
PuppetMaster.Puppet puppet = PuppetMaster.Instance.PuppetInstance;
You don't really need more than one singleton for that. Look at this example:
using System;
// interface for the "inner singleton"
interface IPuppet {
void DoSomething();
}
class MasterOfPuppets {
// private class: only MasterOfPuppets can create
private class PuppetImpl : IPuppet {
public void DoSomething() {
}
}
static MasterOfPuppets _instance = new MasterOfPuppets();
public static MasterOfPuppets Instance {
get { return _instance; }
}
// private set accessor: only MasterOfPuppets can replace instance
public IPuppet Puppet {
get;
private set;
}
}
class Program {
public static void Main(params string[] args) {
// access singleton and then inner instance
MasterOfPuppets.Instance.Puppet.DoSomething();
}
}

Categories

Resources