How to hide methods outside the class - c#

I'm trying to do something, but I don't know if it's possible
I have these classes:
public Class1
{
private Class2 class2;
public Class1
{
this.class2 = new Class2();
}
public Class2 Do()
{
return class2.Build();
}
}
internal Class2
{
public internal Class2 Build()
{
return this;
}
public void Fill()
{
}
}
var class1 = new Class1();
class1.Do().Fill();
I want it when the user types class1.Do (). only the Fill () method is accessible. How can I do this?
The goal would be to prevent class1.Do().Build();

There are quite a few errors in the code posted as mentioned in a comment. For the sake of an example answer, I made all of the troublesome places public. So while this will compile, take it with a grain of salt and adjust your accessibility modifiers appropriately.
Firstly, I created a new interface to only expose Fill, and not Build:
public interface IClass2Helper
{
void Fill();
}
I made a couple of small changes to Class1 and Class2 so that they become compilable, to implement the interface in Class2 and return the interface in the Do() method in Class1:
public class Class1
{
private Class2 class2;
public Class1()
{
this.class2 = new Class2();
}
public IClass2Helper Do()
{
return class2.Build();
}
}
public class Class2 : IClass2Helper
{
public Class2 Build()
{
return this;
}
public void Fill() { }
}
And added a simple test class/method to verify:
class TestProgram
{
static void Main()
{
var class1 = new Class1();
class1.Do().Fill(); //This line is OK
//The below line will have an error since the interface doesn't expose a Build method
class1.Do().Build();
}
}
A fiddle to the code:
https://dotnetfiddle.net/5EPPfO

Related

C# class constructors creating infinite loop

So lets say I have two classes. Class A and Class B like this:
Class A
{
B classB;
public A
{
classB = new B();
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B
{
classA = new A();
}
public void funcIHaveToUseInClassA()
{
}
}
As you can see both classes contain functions that need to be used in the other class. Class A has a function that class B has to use and the other way around. No I can't just put the functions in the other class because they heavily rely on the class they are currently in. So how would I go about doing this? With my method I create an infinite loop and get a stack overflow exception. I hope someone can help me out, thanks in advance.
EDIT:
People are asking me why I need these 2 classes to rely on each other so here it is: Class A manages everything that has to do with a WebBrowser control and class B Manages everything that has to do with a certain page in my program. Class A is being used by multiple pages, which is the reason it needs to be a seperate class. Class A sometimes needs to push info to class B. Class B sometimes needs info from the WebBrowser control class A is managing and that is why it calls a function.
Make classB and classA into public properties and initialize them from another class instead of constructor.
class A
{
public B classB { get; set; }
public void funcIHaveToUseInClassB()
{
}
public void anotherF()
{
classB.funcIHaveToUseInClassA();
}
}
class B
{
public A classA { get; set; }
public void funcIHaveToUseInClassA()
{
}
public void anotherF()
{
classA.funcIHaveToUseInClassB();
}
}
static void main()
{
// entry point
var a = new A();
var b = new B();
a.classB = b;
b.classA = a;
// do what ever you want with a and b
}
You need to pass an instance of one of your classes to the constructor of the other class.
Try this:
Class A
{
B classB;
public A()
{
classB = new B(this);
}
public void funcIHaveToUseInClassB()
{
}
}
Class B
{
A classA;
public B(A arg)
{
classA = arg;
}
public void funcIHaveToUseInClassA()
{
}
}
Update
Or just pass in the instance as a parameter to the methods like in Matt Jacobsen's answer.
Create a private and public accessor, and instantiate the property only when the private object is null, like so:
class A
{
private B _b;
public B b {
get {
if (_b == null) _b = new B();
return _b;
}
}
// Constructor can now be empty
public A()
{
}
}
Pass your reference from B/A in to A/B each time you need to use it. You don't need the constructors.
Class A
{
public void funcIHaveToUseFromClassB(B classB)
{
}
}
Class B
{
public void funcIHaveToUseFromClassA(A classA)
{
}
}

C# Calling variables from other classes

this is probably very simple, but I have always just made one big class and never tried make clean code. Now I am trying and experiencing errors..
So, this is the idea:
class1
{
method1 { value 1; value 2 }
method2 { value 3; value 4 }
method3 { uses method4 from class2 }
}
class2
{
method4 { uses values 1-4 from class1 }
}
I am doing it by calling: class1 c1 = new class1() in method4 and class2 c2 = new class2 in method3.
So this is what happens:
method1, method2 produce values 1-4
method3 calls class2 c2 = new class2
I get into class2, then into method4 and get null/0 values instead of what I made in first step.
Instead of creating a new instance of class1 in method4 you should pass the current class1 instance (accessible through this inside method3) as a parameter to this method to get the same result.
You need to be more specific...
class Class1
{
Class2 _class2;
public Class1(Class2 class2)
{
_class2 = class2;
}
public void method3()
{
//call _class2.method4()
}
}
class Class2
{
Class1 _class1;
public Class2(Class1 class1)
{
_class1 = class1;
}
public void Method4()
{
//call _class1.MethodWhatever()
}
}
So when you need to access variables within a class you can obviously do this simply via the 'public' modifier, however the below example is not best practice but we will get onto that shortly...
public class MyTestClass
{
public int MyAge;
}
This is a field - fields should really be private, and we should use a property to expose the field. However if you did do this, then you can access that like so:
var foo = new MyTestClass();
var hisAge = foo.MyAge;
Of course based on your requirements maybe you don't want the user to access the variable directly, but rather get a value after some computation has been done on other variables.
You can do this like so:
public class MyTestClass
{
private int _gamesPlayed;
private int _gamesLost;
public int NumberOfWins { get { return _gamesPlayed - _gamesLost; } }
}
NumberOfWins is a Property. It computes the values of two of our fields and reutrns it. See how we have the private modifier, these can't been seen outside of the scope of that class. NumberOfWins can be accessed the same way as MyAge in the previous example.
To be honest, it sounds like you are rather using pseudo-code or are a beginner.
I recommend checking out the following articles for a bit more information on what I have stated.
Modifiers - C# Reference
Properties C# Programming Guide
Difference between a Field and a Property in C#
it is really unclear what you want to achieve and how class1 is linked to class2. If your class2 is ONLY useful for the first class then (and only then) you could use nested classes...
class OuterClass {
string value1;
string value2;
string value3;
// ...
class InnerClass
{
OuterClass o_;
public InnerClass(OuterClass o)
{
o_ = o;
}
public string GetOuterString()
{
return o_.value1 + o.value2 + o.value3; //...
}
}
void SomeFunction()
{
InnerClass i = new InnerClass(this);
i.GetOuterString();
}
}
This would create a clear binding from the inner class (class 2) to the outer one. It is not easier though.
Edit: OK, after your edit I see a whole different story..
Well, here is some code for you. I'm not sure it it's what you require. It might help you get started, though. You can try running it here: https://dotnetfiddle.net/#
This is Class1. It exposes some of its data via properties.
public class Class1
{
// these are properties
public int Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; }
public int Value4 { get; set; }
public void Method1()
{
Value1 = 1;
Value2 = 2;
}
public void Method2()
{
Value3 = 3;
Value4 = 4;
}
public void Method3()
{
// uses method4 from class2
var c = new Class2();
c.Method4();
}
}
This is Class2. It calls methods from Class1 and accesses its properties.
public class Class2
{
public void Method4()
{
//uses values 1-4 from class1
var c = new Class1();
c.Method1();
c.Method2();
Console.WriteLine(c.Value1);
Console.WriteLine(c.Value2);
Console.WriteLine(c.Value3);
Console.WriteLine(c.Value4);
}
}
This uses both closes and shows the result:
using System;
public class Program
{
public static void Main()
{
var c1 = new Class1();
c1.Method3();
}
}

How to protected/private class #1 but allow wrapper class #2 to be public and containing in-house class #1?

Is there a way to have wrapper class be exposed as public but other class be private/protected inside the wr
Let's say this script is in DLL file.
protected class Class1
{
public string Foo1() { return "Hello World!"; }
}
public class Class2
{
Class1 class1 = new Class1();
public Class1 Class1_Test
{
get { return class1; }
}
}
Let's say I have Windows Form or webpage.
Here I called Class2.Class1_Test.Foo1(), I am getting a "Hello World!" value.
How do I make both Class1() and CLass1.Foo1() not be visible to the Windows Form?
I am getting syntax error complaining that Class2 is inaccessible due to protection level.
By exposing protected class through public interface.
public interface IClass1
{
string Foo1();
}
protected class Class1 : IClass1 { ... }
public class Class2
{
...
public IClass1 Class1_Test { ... }
}
In your example, if you have a separate assembly containing Class1 and Class2, you could give Class1 an internal constructor, so you could only instantiate it in your assembly.
public class Class1
{
internal Class1()
{
}
public string Foo1() { return "Hello World!"; }
}
public class Class2
{
Class1 class1 = new Class1();
public Class1 Class1_Test
{
get { return class1; }
}
}
Anything outside of the assembly that tries to instantiate Class1 will receive the error
The type 'MyAssembly.Class1' has no constructors defined

Reaching public property of parent class

a simple question :
public class class1
{
public string string1;
public class class2
{
public string string2
{
get{ string tmp = class1.string1; }
}
}
}
I want to be able to reach class1.string1 from class2.string2.get, but I cant. What would you recommend me to change, so that I can do that?
Thanx
Passing class1 reference to class2 in constructor:
public class class1 {
public string string1;
public class class2 {
private class1 _Reference;
public class2(class1 reference) {
if (reference == null) {
throw new ArgumentNullException("reference");
}
_Reference = reference;
}
public string string2 {
get { return _Reference.string1; }
}
}
}
Passing class1 reference to class2 after both classes have been created:
public class class1 {
public string string1;
public class class2 {
private class1 _Reference;
public class1 Reference {
set { _Reference = value; }
}
public string string2 {
get { return _Reference.string1; }
}
}
}
static void usage() {
var foo = new class1();
var bar = new class1.class2();
bar.Reference = foo;
string value = bar.string2;
}
There is no means of accessing a class from within a nested class that I know of. Class nesting doesn't lead to automatic instantiation of the surrounding class, it's just a (usually rather smelly) means of structuring your code.
You would either need a reference to an actual instance of Class1 inside Class2 or you'd need a static method on Class1.
Another way to accomplish this would be to use inheritance, but that's a whole different beast to tame:
public class Class1 {
protected String String1 { get; set; }
}
public class Class2 : Class1 {
public String String2 {
get {
String PropertyFromClass1 = base.String1;
// ...
}
}
}
That said: Your code wouldn't compile, string2's getter doesn't return anything. And please make yourself familiar with C#'s naming conventions.
Thanx for the suggestions. Due to the specific nature of the code, I had to solve this situation with a global public static class in another namespace.
Coming from Java I faced this "problem" when I started developing in C#.
As clearly explained by Dennis Traub and in this article in C# you can't access outer class members or methods. So you have to implement what in Java happens automatically:
class OuterClass {
string s;
// ...
class InnerClass {
OuterClass o_;
public InnerClass(OuterClass o) { o_ = o; }
public string GetOuterString() { return o_.s; }
}
void SomeFunction() {
InnerClass i = new InnerClass(this);
i.GetOuterString();
}
}

Call Constructor Base after Code Execution

Let say we have Class A and Class B. ClassB extends Class A. (ClassB : ClassA)
Now let's say that whenever I instantiate ClassB, I'd like to Run some Random code and only then call "base" to reach ClassA constructor.
Like:
class ClassA
{
public ClassA()
{
Console.WriteLine("Initialization");
}
}
class ClassB : ClassA
{
public ClassB() //: base()
{
// Using :base() as commented above, I would execute ClassA ctor before // Console.WriteLine as it is below this line...
Console.WriteLine("Before new");
//base() //Calls ClassA constructor using inheritance
//Run some more Codes here...
}
}
In the programming language I usually work with, I can do that, by simply calling super() after Console.WriteLine(); But I cant make it in C#. Is there any other syntax or other way to do that?
There's a hacky way of doing it using an instance variable initializer:
using System;
class ClassA
{
public ClassA()
{
Console.WriteLine("Initialization");
}
}
class ClassB : ClassA
{
private readonly int ignoreMe = BeforeBaseConstructorCall();
public ClassB()
{
}
private static int BeforeBaseConstructorCall()
{
Console.WriteLine("Before new");
return 0; // We really don't care
}
}
class Test
{
static void Main()
{
new ClassB();
}
}
The less hacky way of doing it is to rethink how you construct a ClassB to start with. Instead of having clients call the constructor directly, provide a static method for them to call:
public static ClassB CreateInstance()
{
Console.WriteLine("Before initialization stuff");
return new ClassB();
}
Another hack if you can get away with calling a static method.
public class ClassA
{
public ClassA()
{
Debug.WriteLine("Call A Constructor");
}
}
public class ClassB:ClassA
{
public ClassB():this(aMethod())
{
}
private ClassB(object empty):base()
{
Debug.WriteLine("Class B Second Constructor");
}
private static object aMethod()
{
Debug.WriteLine("Run me First");
return null;
}
}
Another elegant solution would be to completely rethink how your objects are constructed. In the constructor of your base class you can call your own construct function, and you omit dependent future constructors, in the following way:
public class ClassA
{
public ClassA()
{
Construct();
}
public virtual void Construct()
{
Console.WriteLine("3");
}
}
public class ClassB : ClassA
{
public override void Construct()
{
Console.WriteLine("2");
base.Construct();
}
}
public class ClassC : ClassB
{
public override void Construct()
{
Console.WriteLine("1");
base.Construct();
}
}
Actually, you can:
class Foo
{
public Foo(string s)
{
Console.WriteLine("inside foo");
Console.WriteLine("foo" + s);
}
}
class Bar : Foo
{
public Bar(string s) : base(((Func<string>)(delegate ()
{
Console.WriteLine("before foo");
return "bar" + s;
}))())
{
Console.WriteLine("inside bar");
}
}
class Program
{
static void Main(string[] args)
{
new Bar("baz");
}
}
Output:
before foo
inside foo
foobarbaz
inside bar
But I will prefer to not use this trick if it is possible.
C# doesn't allow calling base constructors inside constructor bodies, different from Java.
You can't do that with C#. Your best bet is to extract that code into it's own method in the parent and then call that from the child when you're ready.
I am surprised noone has suggested using an abstract method - though it does rely on the base being implemented as an abstract class which wont work for all cases (although you could simply fork the inheritance and stack the non-abstract on top if yu have to). This has the advantage of ensuring the integrity of your code without resorting to hackiness. Because we are using abstract, it is not possible to instantiate the derived class without declaring initCode.
using System;
abstract class ClassA
{
internal abstract initCode();
public ClassA()
{
initCode();
Console.WriteLine("Initialization");
}
}
class ClassB : ClassA
{
public ClassB()
{
}
internal override initCode()
{
Console.WriteLine("Before new");
return 0; // We really don't care
}
}
//If you need to effectively get the non-abstract of ClassA
class ClassC : ClassA
{
public ClassB()
{
}
internal override initCode()
{
}
}
You can not call base constructor.
But a different thing is that when you declare an object of derived class both constructor derived and base is called.
class ClassA
{
public ClassA()
{
Console.WriteLine("Initialization");
}
}
class ClassB : ClassA
{
public ClassB() //: base()
{
// Using :base() as commented above, I would execute ClassA ctor before // Console.WriteLine as it is below this line...
Console.WriteLine("Before new");
//base() //Calls ClassA constructor using inheritance
//Run some more Codes here...
}
}
void main(string[] args)
{
ClassB b = new ClassB();
}
Recently I ran into a scenario where I needed to calculate some logic before passing the result into base.
I could just do something like
public SomeConstructor: base(FlagValue == FlagValues.One || FlagValues.Two ? "OptionA" : "OptionB")
{
}
But I find that to be ugly, and can get really long horizontally. So I opted instead to use Func Anonymous methods.
E.g. imagine you have a base class,
public class SomeBaseClass
{
public SomeBaseClass(Func<string> GetSqlQueryText){
string sqlQueryText = GetSqlQueryText();
//Initialize(sqlQueryText);
}
}
Now you inherit from that and want to do some logic to determine the sql query text,
public class SomeSqlObject : SomeBaseClass
{
public SomeSqlObject(ArchiveTypeValues archiveType)
: base(delegate()
{
switch (archiveType)
{
case ArchiveTypeValues.CurrentIssues:
case ArchiveTypeValues.Archived:
return Queries.ProductQueries.ProductQueryActive;
case ArchiveTypeValues.AllIssues:
return string.Format(Queries.ProductQueries.ProductQueryActiveOther, (int)archiveType);
default:
throw new InvalidOperationException("Unknown archiveType");
};
})
{
//Derived Constructor code here!
}
}
In this way you can execute code before Base is called and (in my opinion) it's not really hacky.
I had the same problem. I found this solution to be the best if you don't have access to the base class.
public class BaseClass
{
public BaseClass(string someValue)
{
Console.WriteLine(someValue);
}
}
public class MyClass : BaseClass
{
private MyClass(string someValue)
: base(someValue)
{
}
public static MyClass GetNewInstance(string someValue, bool overrideValue = false)
{
if (overrideValue)
{
someValue = "42";
}
return new MyClass(someValue);
}
}

Categories

Resources