Consider the following example:
interface IPropertyCollection
{
public MethodWrapper GetPropertySetterByName(string name);
//<<-- I want the implementation from A and B merged into here somehow
}
class A : IPropertyCollection
{
static PropertyMap properties = new PropertyMap(typeof(A));
public MethodWrapper GetPropertySetterByName(string name)
{
return properties.SomeFunc(name);
}
}
class B : IPropertyCollection
{
static PropertyMap properties = new PropertyMap(typeof(B));
public MethodWrapper GetPropertySetterByName(string name)
{
return properties.SomeFunc(name);
}
}
I want to have a static member in each class keeping track of things in that class only and i want it to behave exactly the same for every class, but with different content. Each static member should only keep track of one single class. I want to be able to get access to the classes' static member by just having an instance of any IPropertyCollection.
Something like this:
IPropertyCollection a = new A();
IPropertyCollection b = new B();
a.GetPropertySetterByName("asdfsj"); //Should end up in static A.properties
b.GetPropertySetterByName("asdfsj"); //Should end up in static B.properties
Now this will work with my example code but i don't want to repeat all those lines inside A and B and 50 other classes.
Use a (curiously recurring) generic common base class:
abstract class Base<T> : IPropertyCollection where T : Base<T> {
static PropertyMap properties = new PropertyMap(typeof(T));
public MethodWrapper GetPropertySetterByName(string name) {
return properties.SomeFunc(name);
}
}
class A : Base<A> { }
class B : Base<B> { }
Since the base class is generic, a different "version" of its static members will be "generated" for each different type parameter.
Just be careful with evil dogs :-)
class Evil : Base<A> { } // will share A's static member...
Static members can't be inherited. They belong to the class they are declared on.
Related
This question already has answers here:
When and why would you seal a class?
(5 answers)
Closed 2 years ago.
I know that you can not inherit from a class once sealed is used but I am confused what is the difference between these two: private and sealed?
Can't we make the base class members private if we don't want to inherit them instead of the whole class? What is the point of using sealed class?
private: private limits the visiblity to a scope. Declaring a private class within a class means that sub-class can't be seen from outside of the class.
This is also true for methods and properties - they can be seen within the class, but not to any consumers or inheritors.
private keyword is used for declaring class.
sealed: If a class is declared as sealed, that means that you cannot inherit from the class. sealed class can be used when a class is internal to the operation of the library, class or why you do not want that class to be overridden because it may affect the functionality.
sealed keyword is used for declaring class
example
public class Parent {
// some thing at here
private readonly SubClass sc;
// ctor
public Parent () {
sc = new SubClass();
}
public string foo () {
return sc.bar();
}
private class SubClass {
// have some thing here
public string bar() {
//..............
return "...........";
}
}
}
You need to understand difference between inheritability and accessibility.
If you want to make your class non-inheritable, making it sealed is the best option. Also a class can not be protected, private or internal protected. Only sub class can have those access specifiers. A normal class which is directly under a namespace can only be public or internal.
Now coming to you point of making all the members private in the base class. Doing that does not serve any purpose.
You inherit a class only to reuse certain properties and/or method or override them in the inherited class. If you make all the members private in the base class you won't be able access them outside even using the object of base class.
Then what's the point of having them in the base class.
public class MyClass
{
private void MyMethod() //You can not inherit this method but you can not use it using 'MyClass' also.
{
//Some code.
}
}
MyClass myObj = new MyClass();
myObj.MyMethod(); // You can not do this as the method is private.
Now if you inherit this class in another class
public ChildClass : MyClass
{
public void ChildMethod()
{
// Some Logic
}
}
Now when you do
MyClass obj = new ChildClass();
You can not do
obj.MyMethod(); //coz this is private method.
You can not do following too.
obj.ChildMethod(); //coz that method is not known to MyClass.
So if you are making members private just for the sake of making them not available for inheritance, you are losing their accessibility from the base class too.
Understood your confusion,
First of all there is no independent private class inside a namespace, compiler throws an error.
If you make a method void m1() private inside public class A, then the method m1 is not accessible from public class B.
Sealed classes are accessible to other classes though it stops inheritance, meaning you cannot use it to derive from.
In the example below, you wont be able to access the method privatemethod from the Main(), but sealed class and sealed method can be accessed. So sealed can be accessed though cannot be inherited, that's the difference.
namespace ConsoleApp1
{
using System;
public class A
{
public virtual void test()
{
Console.WriteLine("Class A");
}
}
public class C
{
public void testSealFromOutsideClass()
{
B instanceB = new B();
instanceB.test();
}
}
public sealed class B : A
{
public override void test()
{
Console.WriteLine("Class B");
}
private void Privatemethod()
{
Console.WriteLine("Printing from a private method");
}
}
//public class C : B {}
public class TestSealedClass
{
public static void Main()
{
A a = new B();
a.test();
C c = new C();
c.testSealFromOutsideClass();
B b = new B();
Console.Read();
}
}
}
With the abstract following class:
public abstract class A
{
public static string MyMethod()
{
return "a";
}
}
Why can't I built this derived abstract class:
public class B<T> where T : A
{
public void AnotherMethod()
{
var S1 = base.MyMethod(); // not allowed
var S2 = T.MyMethod(); // not allowed
}
}
I don't understand why since MyMethod will be available in type T.
There are two misconceptions in your question that collectively prevent both your attempts from working.
First your B class is not in any way derived from the A class, you have only said that it takes a generic parameter that must inherit from A.
Second as the user #recursive pointed out, static methods do not participate in inheritance so MyMethod would only ever be available as A.MyMethod()
You can make at least your first attempt work if you remove the static modifier and make B inherit from A instead of using generics.
// Removed the static modifier
public abstract class A
{
public string MyMethod()
{
return "a";
}
}
// Made B inherit directly from A
public class B : A
{
public void AnotherMethod()
{
var S1 = base.MyMethod(); //base technically isn't required
}
}
Aside from the fact that A.MyMethod is static, which clearly will not work since anything static does not take part in inheritance, even if you made it not static it still will not work. For example, this will not work either:
public abstract class A {
public string MyMethod() {
return "a";
}
}
public class B<T> where T : A {
public void AnotherMethod() {
var S1 = base.MyMethod(); // Line 1
var S2 = T.MyMethod(); // Line 2
}
}
Why?
You are saying where T : A which means that type T has to be a derived type from A. Your class B<T is not a derived type of A so Line 1 will not work.
But why is Line 2 not working?
T is a type and if T is inheriting A, then objects of type T will be able to do that. If you changed it like this, then it will work:
public abstract class A {
public string MyMethod() {
return "a";
}
}
public class B<T> where T : A {
public void AnotherMethod(T t) {
t.MyMethod();
}
}
public class C : A {
}
public class BClosed : B<C> {
public void Foo(C c) {
c.MyMethod();
this.AnotherMethod(c);
}
}
In the above code, C derives A which was your restriction. Then BClosed closes the generic type saying T is C so now you can call MyMethod of A and AnotherMethod of your generic.
Also, when you have a generic class you should use the generic type otherwise I do not see the use. So this is useless since it has no generic code:
public class B<T> where T : A {
public void AnotherMethod() {
}
}
I have a few classes. Lets say:
public class A
{
public void SomeAction()
{
Debug.Write("I was declared in class: and my name is:");
}
}
And
public class B
{
public static A myClass = new A();
}
public class C
{
public static A myClass = new A();
}
public class D
{
public static A myClass = new A();
}
What I want "SomeAction" in class A to do is to print out which class it was initialized in.
So that for example in another class I called C.myClass.SomeAction(); it would print out "I was declared in class C my name is myClass"
I hope this makes sense.
The reasons im doing this is for debugging within automated testing. I understand its not the best way to do things but its a requirement of the business.
This requirement can be satisfied without inheritance or passing the object; we can get the name of the class that calls the constructor from within the body of the constructor by examining the stack.
public class A
{
private string _createdBy;
public void SomeAction()
{
Console.WriteLine("I was declared in class [{0}]", _createdBy);
}
public A()
{
var stackFrame = new StackFrame(1);
var method = stackFrame.GetMethod();
_createdBy = method.DeclaringType.Name;
}
}
In terms of performance, I am assuming that you are not creating many instances of these objects. You could also predicate this on whether you are doing a DEBUG build or on some other setting, so that this stuff is skipped entirely in your production executables.
Since you only reference an instance of class A in your other classes, I think there is no other way then setting a reference to the type which created class A, like eddie_cat already mentioned. You could do something like this:
public class B
{
public static A myClass = new A(typeof(B));
}
And then your class A would look like:
public class A
{
// store the parent type
private Type mParentClass;
// provide parent type during construction of A
public A(Type parentClass)
{
mParentClass = parentClass;
}
// note that method cannot be static anymore, since every instance of A might
// have a different parent
public void SomeAction()
{
// access field where parent type is stored.
Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
}
}
I think you have two choices. Either set a property in A, or inherit from A. Personally, I prefer inheriting from A, because then A could just use GetType().
public class A
{
public void SomeMethod()
{
Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
}
}
public class B : A
{
}
var instanceOfB = new B();
instanceOfB.SomeMethod();
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.
i'm writing some ashx handlers which are wired to a mock service, and i want them to share the mock service instance. The simplest approach i though was creating a static instance
public class AbstractHandler
{
static IService _impl;
public static IService Impl
{
get
{
if (_impl == null)
{
_impl = new MockService();
}
return _impl;
}
}
}
However, i'm wondering if this is going to work at all; will different handlers that inherit from this class will have their own static _impl reference or they will be shared?
A static field exists once, except in the case of a generic type, in which case it exists once for each used combination of generic parameters.
Even if the class is a base class, possibly abstract, the same rules apply. Note that if the class in which the field is declared is not generic, the field will exist once, even if descendants are generic. The rule about "once per combination ..." only comes into play if the class that declares the static field is generic.
So, if your question instead had been:
How can I make the static field be per descendant and not just once
Then the answer would've been that you should make your base class generic, and pass the descendant type as the generic parameter.
Example LINQPad script to demonstrate the "once per generic parameter combination":
void Main()
{
var i = new Test<int>();
var s = new Test<string>();
Test<bool>.UsageCount.Dump();
Test<int>.UsageCount.Dump();
Test<string>.UsageCount.Dump();
}
public class Test<T>
{
public static int UsageCount;
public Test()
{
UsageCount++;
}
}
Output:
0
1
1
Example to demonstrate with base class:
void Main()
{
var i = new Test1();
var s = new Test2();
Test1.UsageCount.Dump();
Test2.UsageCount.Dump();
Test3.UsageCount.Dump();
}
public abstract class Base<T>
{
public static int UsageCount;
protected Base()
{
UsageCount++;
}
}
public class Test1 : Base<Test1>
{
}
public class Test2 : Base<Test2>
{
}
public class Test3 : Base<Test3>
{
}
Output:
1
1
0