I have two classes in a namespace and these classes need to call each other like this:
public class A
{
void MethodVisibleToB() {}
}
public class B
{
void MethodVisibleToA() {}
}
I want the methods to not be seen neither from inside the dll nor from outside. I wanted only class A to see B.MethodVisibleToA and only class B to see A.MethodVisibleToA.
I usually restrain visibility of a method with nested classes, but this time it is not possible as well as unnecessarily complex. Can you suggest a way to prevent this methods to be called from outside?
The options I have now are not that good:
make all public (meh),
make all internal and move A and B in another dll (not doable)
Edit: I forgot to mention that the classes are in the same namespace in the same assembly
Solution: I took Mrinal Kamboj's suggestion and implemented the interfaces explicitly:
internal interface IA
{
void VisibleByB();
}
internal interface IB
{
void VisibleByA();
}
public class A : IA
{
void IA.VisibleByB() { }
}
public class B : IB
{
void IB.VisibleByA() { }
}
Event more pervert solution to a pervert problem: this will prevent the two interfaces and relative methods to be accessed from other classes and even subclasses:
public static class ClassAreNotMeantToBeUsedThisWay
{
interface IA
{
void VisibleByB();
}
interface IB
{
void VisibleByA();
}
public class A : IA
{
void IA.VisibleByB() { }
}
public class B : IB
{
void IB.VisibleByA() { }
}
}
Try using an Interface and implement Explicitly as follows:
interface InterfaceA
{
void MethodVisibleToB();
}
interface InterfaceB
{
void MethodVisibleToA();
}
public class A : InterfaceA
{
void InterfaceA.MethodVisibleToB() { }
}
public class B : InterfaceB
{
void InterfaceB.MethodVisibleToA() { }
}
Access as follows:
InterfaceA a = new A();
a.MethodVisibleToB();
InterfaceB b = new B();
b.MethodVisibleToA();
this way method would be available when wrapped up in an interface type, will not be available when not wrapped in an Interface type, but a class type
You can mark the methods as internal
Internal types or members are accessible only within files in the same assembly
See the following example:
public class A
{
internal void MethodVisibleToB() {}
}
public class B
{
A aInstance = new A();
internal void MethodVisibleToA()
{
aInstance.MethodVisibleToB(); // this can only be called by methods that are within the same assembly as B
}
}
Addendum
If you need to access the method from the outside, you can use InternalsVisibleToAttribute in the assembly where A and B are located. Anyway, I'd recommend this for a very restricted scope only, e.g. (unit-)tests. Place this line in any .cs file in your assembly (without an namespace)
[assembly: System.InternalsVisibleTo("MyAssembly.Tests")]
Related
I stumbled across an interview question related to OOPS. Here is the question:
There is a base class A with 5 methods. Now how should I design the class such that if a class B inherits class A, only 3 methods are exposed. And if a class C inherits class A, the rest of the 2 methods are exposed.
Any thoughts ??
if A is partial and you have 2 namespaces then:
namespace the_impossible
{
class Program
{
static void Main(string[] args)
{
B b = new B();
C c = new C();
b.m1();
b.m2();
b.m3();
c.m4();
c.m5();
}
}
namespace A_1
{
public partial class A
{
public void m1() { }
public void m2() { }
public void m3() { }
}
}
namespace A_2
{
public partial class A
{
public void m4() { }
public void m5() { }
}
}
class B : A_1.A
{
}
class C : A_2.A
{
}
}
It should not be possible in any object-oriented language, otherwise it would break the Liskov substitution principle. Substituting a B for an A should not reduce its correctness (meaning methods should not suddenly be unavailable)
However, there is still some ambiguity in the question that allows for some "out-of-the-box" thinking. Here are questions I would pose back to the interviewer:
What do you mean by "exposed"?
Do the 5 methods in A have to be public?
Does the "exposition" by C need to be implicit or can the be explicitly exposed (e.g. pass-through)
Based on those answers you could either come up with possible options using internal, explicit interface implementations, etc.
I think it was a trick or even dumb question. To achieve this, we must break the Liskov substitution principle. You shouldn't preseve the hierarchy of the classes.
Maybe you just should use interfaces instead:
public class A {} //why we even need this class?
public class B : A, I3Methods
{
public void Method1() { }
public void Method2() { }
public void Method3() { }
}
public class C : A, I2Methods
{
public void Method4() { }
public void Method5() { }
}
public interface I3Methods
{
void Method1();
void Method2();
void Method3();
}
public interface I2Methods
{
void Method4();
void Method5();
}
The only way I can think of is to have them all private in A and then expose them through encapsulation in B and C... But they are not exposed, only executed... So it is half right.
I also think that's impossible.
But to give an approximate answer:
Make 3 methods in A virtual, then implement them in B. Then override those 2 methods in C.
Nobody says that the 5 methods of class A should be exposed when writing them. In C# you could simply write 5 protected methods in class A and expose those you wish to be accessible by writing some hiding methods with the new modifier like this - although this wouldn't actually expose the methods directly they are merely wrapped.
class A
{
protected void M1() { }
protected void M2() { }
protected void M3() { }
protected void M4() { }
protected void M5() { }
}
class B : A
{
public new void M1()
{
base.M1();
}
public new void M2()
{
base.M2();
}
public new void M3()
{
base.M3();
}
}
class C : A
{
public new void M4()
{
base.M4();
}
public new void M5()
{
base.M5();
}
}
In your comments, you mentioned that you were interested if this could be done in any other language. You can kind of do it in C++ through the use of the using keyword. So, starting with class A:
class A {
public:
int Method1() { return 1; }
int Method2() { return 2; }
int Method3() { return 3; }
int Method4() { return 4; }
int Method5() { return 5; }
};
Then you define class B, using private inheritance (essentially you can't auto cast from B to A and all public methods in A become private methods in B).
class B: private A {
public:
// We want to expose methods 1,2,3 as public so change their accessibility
// with the using keyword
using A::Method1;
using A::Method2;
using A::Method3;
};
Do the same for class C, exposing the other two methods instead:
class C: private A {
public:
using A::Method4;
using A::Method5;
};
Or if you're supposed to expose all the methods through C, simply use public inheritance and everything exists:
class C: public A {
public:
};
For usage:
B *b = new B();
b->Method1(); // This works, Method1 is public
b->Method4(); // This fails to compile, Method4 is inaccessible
The reason I said kind of above is because you can work around it by explicitly casting the instance of B to an A:
A *brokena = b; // This wouldn't compile because the typecast is inaccessible
A *a = (A*)b; // This however does work because you're explicitly casting
a->Method4(); // And now you can call Method4 on b...
I know, it is to late to respond. Just thought of sharing my thoughts:
Define Class A as a base class.
Have intermediate child classes A1 -> M1,M2,M3 and A2 -> M4, M5 deriving from Class A
Now, you can have
1) Class B inheriting A1
2) Class C inheriting A2
These two classes are still derived from Class A.
And also we are not breaking liskov substitution principle.
Hope, this gives clarity.
I would like to have interace A. Which will allow objects of type A generate other objects of type A.
I need the same behavior for type B. In my application is true that all B are also A. So I would like B to be derived from A.
This is my try:
public interface A {
A method1();
}
public interface B : A {
overrride B method1();
void otherMethod();
}
Note that override keyword dosn't compile here. The only way to make the project compile is make the interface B look as follows:
public interface B : A {
//A method1(); /* commented out because it is inherired */
void otherMethod();
}
However I would like to promise by interface B, that objects of this type have method to produce other objects of type B.
Implementation of interface B could look like:
class Foo : B {
B metod1();
}
Where I want B metod1() to be implemantation of B method1() from interface B and I also want the same method to be implementation of A method1() from interface A. I expect the same behavior in all classes implementing interface B. So I don't want to implement method1 each time twice for both interfaces.
I am doing this in c# with interfaces. But I believe that similar question could be interesting even with classes and possibly also in Java.
The only way to do this properly is using generics like this:
public interface A<T> where T : A<T>
{
T method1();
}
Then B looks like this:
public interface B : A<B>
{
void otherMethod();
}
And finally, implementing a class would go like this:
public class Bravo : B
{
public B method1() { return null; }
public void otherMethod() { }
}
However, you can use the new keyword to shadow a method in an interface, but this isn't a great idea as it makes it harder to reason about your code as it breaks normal inheritance.
Try this:
public interface A
{
A method1();
}
public interface B : A
{
new B method1();
void otherMethod();
}
public class Bravo : B
{
A A.method1() { return null; }
public B method1() { return null; }
public void otherMethod() { }
}
That sure is possible, use the new keyword here, not the override and implement the overridden interface explicitly.
Edit:
Adjusted the sample based on your comments. You will still need the explicit interface implementation IFoo IFoo.GetData() { return GetData(); }, but this one has no code on its own, since its just calling he implicit implementation public INewFoo GetData() { return new Foo(); }.
Here is an example:
public interface IFoo
{
IFoo GetData();
}
public interface INewFoo : IFoo
{
new INewFoo GetData();
}
public class Foo : INewFoo
{
IFoo IFoo.GetData() { return GetData(); }
public INewFoo GetData() { return new Foo(); }
}
I am using C#
Scenario: Same project
FolderA - ClassA
FolderB - ClassB
I have a method in ClassB that needs the methods from ClassA.
How can I do that?
The folder part does not matter, but one common way to expose methods to other classes is to make them public. You can either use static or instance methods.
Ex
public class A
{
public void SomeMethod(){}
public static void SomeStaticMethod(){}
}
public class B
{
public B()
{
A a = new A();
a.SomeMethod();
A.SomeStaticMethod();
}
}
Another alternative is to use inheritance and let class A inherit from class B
public class A : B
{
public A()
{
//you can now call the methods defined in B
base.SomeMethod();
}
}
Above is an example of how to do it.
using System;
public class Base
{
public Base()
{
}
public void M1()
{
}
public void M2()
{
}
public void M3()
{
}
}
public class Derived : Base
{
//this class should get only method 1
}
public class SecondDerived : Base
{
//this class should get only method 2 and method3
}
The requirement is : the base class contains the 3 methods M1, M2, M3.
The derived class should inherit only M1 and SecondDerived should inherit only M2 and M3.
How can this be done?
You cannot selectively inherit methods like this. A derived class automatically inherits all public methods of the base class. I suggest you to split the Base class into two classes:
public class Base1
{
public Base1()
{
}
public void M1()
{
}
}
public class Base2
{
public void M2()
{
}
public void M3()
{
}
}
public class First : Base1
public class Second : Base2
You cannot do it in this way. Inheritance implies an "IS A" relationship.
If SecondDerived would not have a M1() then it would not be compatible with a reference to a the class Base.
So maybe you shouldn't be using inheritance for whatever problem you're solving.
It is not possible to do what you want with inheritance.
It seems you have no intention of overriding, you simply want to "inherit" behavior from the base class selectively. You could do this using a "has a" relationship:
public class Base
{
internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary
public Foo Mehtod1() {...}
public Foo Mehtod2() {...}
public Foo Mehtod3() {...}
}
Then simply do the following:
class A
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method1() { return this.internalBase.Method1(); }
}
class B
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method2() { return this.internalBase.Method2(); }
public Foo Method3() { return this.internalBase.Method3(); }
}
UPDATE: A possible alternative solution is to make your Base class methods virtual and override them all in your derived classes, throwing NotSupportedExceptions in those methods that you do not want the class to make available. I don't really like this solution but it has the advantage of not loosing the polyphormism inheritance gives you which might be useful if you have some core base functionality which all derived classes will share (in your example you seem to imply they wont).
It is possible by adding Obsolete attribute
public class A
{
public virtual void M1() { }
public void M2() { }
public void M3() { }
}
public class B : A
{
[Obsolete("You can not use this", true)]
public sealed override void M1()
{
}
}
public class C : B
{
public void Test()
{
// Will show error
base.M1();
}
}
I am working on a small project and I came across that problem.
The project output is a library containing an interface. I would like to implement that interface and seal the functions in it like this if possible:
public interface ITest
{
void SomeMethod();
}
class A : ITest
{
public sealed override SomeMethod()
{
}
}
The idea is to have the interface available to everyone and have some specialized class that implements it. The exception is that I want to make sure that if someone create a specialized class of type A, he/she won't be able to change the method's behavior.
The problem is you can't put the "override" keyword in there since the method isn't declared as "virtual" in the interface. And you can't declare it as "virtual" in the interface since it's not allowed. And you can't remove the "override" keyword since it's needed by "sealed".
Any workaround or brainstorming idea would be welcome, but if someone can come up with a solution that includes an interface, I'd be really happy to learn it!
Thanks!
EDIT: Forget this question! Like Ani said, I forgot that by default method in C# are sealed. Seems like it's always good to go back to the basics once in a while...
I may have completely misunderstood the question, but if your intention is to seal the method in A, you can just do:
class A : ITest
{
public void SomeMethod() { ... }
}
Unlike Java, methods in C# are sealed by default. Subclasses of A won't be able to override the method since it hasn't been marked virtual.
On the other hand, if your intention is to mark the method 'almost sealed' in the interface, so that it forces upon an implementing class to immediately seal it, that isn't possible. It isn't (and shouldn't be) the business of the interface to dictate such details of implementation - an interface is meant to represent a specification.
Use an abstract base class with internal visibility. This base class is not visible outside of the library but allows you to seal the method and the class still implements the interface.
public interface ITest
{
void SomeMethod();
}
internal abstract class SuperA : ITest
{
public abstract void SomeMethod();
}
class A : SuperA
{
public sealed override void SomeMethod()
{
}
}
Your understanding of sealed keyword is incorrect. As a method modifier, sealed is used to prevent a virtual method(defined in the base class) to be override in the next generation of derived classes. For example:
class Base
{
public virtual void M() { }
}
class Derived : Base
{
public sealed override void M() { }
}
class A : Derived
{
public override void M() { } //compile error, M is sealed in Derived
}
Developers can always use new modifier to define a method with the same name in the derived class, that hides the one defined in the base class.
if someone create a specialized class
of type A, he/she won't be able to
change the method's behavior.
If "specialized class" means a class derived from A, the answer is: he can always hide the method in A, but he can't change the method's behavior.
Why not use an abstract class like below.
Haven't tested it but this should work?
public abstract class Test
{
public virtual void SomeMethod() {}
//OR
public abstract void SomeMethod();//MSDN says:
//an abstract method is implicitly virtual
}
class A : Test
{
public sealed override SomeMethod()
{
}
}
Methods in C# are sealed by default.. Here is a sample
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.SomeMethod();
b ss = new b();
ss.SomeMethod();
Console.ReadLine();
}
}
public interface ITest { void SomeMethod(); }
class A : ITest { public void SomeMethod() {
Console.WriteLine("SomeMethod Called from Class A object");
} }
class b : A
{
//public override void SomeMethod()
//{
// Console.WriteLine("Called from Class B Object");
//}
}