I need a certain class to contain a static member that keeps track of everytime an instance of that class is instantiated, essentially so that each instance of the class has a unique index. It works with a non-generic class but this generic implementation fails whenever the type T differs between instances:
class A<T>
{
private static int counter;
private static int Counter {
get {
Increment();
return counter;
}
}
private static void Increment() {
counter++;
}
public int Index;
public A()
{
this.Index = Counter; // using A<T>.Counter makes no difference
Console.WriteLine(this.Index);
}
}
class Program
{
static void Main(string[] args)
{
var a = new A<string>();
var b = new A<string>();
var c = new A<string>();
var d = new A<int>();
}
}
The output is:
1
2
3
1
As soon as the type T switches to int instead of string, the counter resets.
Does this fail by design, and if so what is the reason or how can I get around it? Or is it a bug? It makes sense to some degree because the type T, being generic, is in the class declaration, but..
Each different T creates a new class for A<T> and hence distinct static counters.
To get around this you can use inheritance like so:
abstract class A
{
protected static int counter;
}
class A<T> : A
{
private static int Counter {
get {
Increment();
return counter;
}
}
private static void Increment() {
counter++;
}
public int Index;
public A()
{
this.Index = Counter;
Console.WriteLine(this.Index);
}
}
Not a bug - this is by design, and is a consequence of how generics work.
A generic type like your A<T> serves as a template - when you use type parameters, the compiler generates an actual class with that type T, and a different one will be created for each different type T.
This explains the results you see - there is a static field for the A<int> and another one for the A<string>.
This is because different types are generated under the hood for classes with different generic type parameters. This difference is only for the value type parameters as kindly noted by Ben in comment.
Check out these MSDN articles:
Generics in the Run Time
Reflection and Generic types
EDIT:
Consider following code:
public abstract class GenericBase<T>
{
public static int Counter { get; set; }
}
public class GenericInt : GenericBase<int>
{
}
public class GenericLong : GenericBase<long>
{
}
public class GenericDecimal : GenericBase<decimal>
{
}
[TestFixture]
public class GenericsTests
{
[Test]
public void StaticContextValueTypeTest()
{
GenericDecimal.Counter = 10;
GenericInt.Counter = 1;
GenericLong.Counter = 100;
// !! At this point value of the Counter property
// in all three types will be different - so does not shared across
// all types
}
}
A generic class is a template from which other classes are created. A List<String> and a List<int> are two completely different classes, despite them both originating from List<T>.
Have your generic classes reference a non-generic class that holds the counter. Do not put the static class inside the generic class. This will cause the static class to be generated for each value of T.
class A<T>
{
private static int Counter {
get {
ACounter.Increment();
return ACounter.counter;
}
}
public int Index;
public A()
{
this.Index = Counter;
Console.WriteLine(this.Index);
}
}
static class ACounter
{
static ACounter() {
counter = 0;
}
public static int counter {get; private set;};
public static void Increment() {
counter++;
}
}
Generics with different type parameters are different types. So A<int> and A<string> are different classes, and so are allocated different statics.
This is by design. An instance of A<int> is not an instance of A<string> they are different classes so there are 2 static variable one for each class.
A<int> is actually a different class than A<string>, hence they have different static counters
This is why Resharper flags static variables in generics because so few programmers seems to understand statics and especially statics in generics
Related
Recently, I had a need to process the private data contained in the base class using the methods of the child class. My base class could only contain domain-specific types (it only represents data). So first I decided to create a child-class in another project and implement the processing logic in it. But the problem is that once you create an instance of the base class, you can't cast it to the child type:
public class A
{
protected int member1;
public A(int value)
{
member1 = value;
}
}
public class B : A
{
public B (int value) : base(value)
{ }
public void DoSomething()
{
Console.Write(member1 * member1);
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
B obj2 = (B)obj1; // InvalidCastException
obj2.DoSomething();
}
}
And I started thinking towards extension methods. However, you can't just access the protected fields of the class from them. In the end, I tried to combine the two approaches.
Here's my solution:
Make sure that you are allowed to add new methods to your base class and that your class is not sealed.
Add protected static method which returns the protected member you need.
Create an Extension class for your base class.
In extension class create a private nested class.
Inherit your nested class from your base class.
Create static method in nested class and implement the processing logic in (you can call static protected method from base class to get protected member from base class).
Create extension method in extension class and call static method of nested class in it.
The sample code is shown below:
public class A
{
protected int member1 = 0;
public A() {}
public A(int value)
{
member1 = value;
}
protected static int GetProtectedMember(A objA)
{
return objA.member1;
}
}
public static class AExtensions
{
public static void DoSomething(this A objA)
{
B.DoSomething(objA);
}
private class B : A
{
public static void DoSomething(A objA)
{
// objA.member1 // it's not allowed
int protectedFromA = A.GetProtectedMember(objA);
int sqr = protectedFromA * protectedFromA;
Console.WriteLine(sqr);
}
}
}
class Program
{
static void Main(string[] args)
{
A obj1 = new A(5);
obj1.DoSomething(); // 25
}
}
This way you can keep the classes that represent the data in a separate project and have multiple implementations of processing this data in different projects.
Is there any difference between the two. What would be the reason that I define a generic class of type T.
If I just define the methods does it mean the same as defining the class of Type T.
void Main()
{
Test1<int> x = new Test1<int>();
x.Test1Method(1);
Test2 x1 = new Test2();
x1.Test2Method(1);
}
public class Test1<T>
{
public void Test1Method<T>(T x)
{
Console.WriteLine(x);
}
}
public class Test2
{
public void Test2Method<T>(T x)
{
Console.WriteLine(x);
}
}
In class Test1, the T that is defined on the class level is different from the T defined on the Test1Method method. This makes the T on the class level useless.
You could use Test1 like this:
Test1<string> x = new Test1<string>();
x.Test1Method(1);
In this case the first T is string and the second T is int.
As it is right now, Test1 is no different than Test2.
It would have been different if you defined Test1 like this:
public class Test1<T>
{
public void Test1Method(T x)
{
Console.WriteLine(x);
}
}
Notice after this change how Test1Method does not have a generic T parameter. Now this class is different from Test2 in that in Test1 you specify T upon object construction, and in Test2 you can have a different T everytime you invoke Test2Method.
Here is an example of how you can use the two classes (after the change I introduced):
Test1<int> x = new Test1<int>();
x.Test1Method(1); //valid
x.Test1Method(2); //valid
x.Test1Method("str"); //invalid
Test2 x1 = new Test2();
x1.Test2Method(1); //valid
x1.Test2Method("str"); //valid
It is not the same, but the difference is only evident when you have properties/fields with a generic type (which you can only do when the class itself is generic) or you have multiple methods:
public class ArrayWrapper<T> {
private T[] elements;
public T get(int index) {
return elements[index];
}
public void set(int index, T value) {
elements[index] = value;
}
}
Without <T> on the class, the T[] elements field will not compile, and it would be possible to use different types in get() and set() on the same object.
(As Lee pointed out, you probably don't want to use <T> on the methods when you have it on the class, as having it in both places would actually introduce another generic type parameter for the method which is independent of the one for the class...)
public class Foo
{
public const int type = 1;
}
Why can't i do this? Is there a reason behind it or am I trying to access the constant in a wrong way?
new Foo().type;
I know I can do Foo.type but given my scenario, I cant do that. For example if I have two class which inherit from a base class like this:
public class Base
{
...
}
public class Foo : Base
{
public const int type = 0;
}
public class Bar : Base
{
public const int type = 1;
}
public static void printType(Base b)
{
Console.WriteLine(b.type);
}
I would want to get the type property of the class sent through the printType() function but I cant since I can only access the type from the Class, not the object its self.
A work around would be to do
if(b is Foo){
Console.Write(Foo.type);
}elseif....
but this seems stupid and not viable if you have many sub classes of Base
Solution
I ended up using readonly instead of const like this:
public readonly int type = 0;
Yes, you're trying to access it in the wrong way. A constant isn't associated with an instance of a type - it's associated with the type itself. So you want:
int x = Foo.type;
Basically, const members are implicitly static, and C# doesn't let you access static members as if they were instance members, via a value. (Note that in .NET naming conventions, it should be Type rather than type.)
EDIT: Now that you've explained the actual situation, it appears you're trying to use polymorphism, which won't work for constants. So instead, you should have an abstract property in the base class, implemented in subclasses.
public abstract class Base
{
public abstract int Type { get; }
}
public class Foo : Base
{
public override int Type { get { return 0; } }
}
public class Bar : Base
{
public override int Type { get { return 0; } }
}
Alternatively, just have a normal property in the base class which is populated via the base class constructor:
public class Base
{
private readonly int type;
public int Type { get { return type; } }
protected Base(int type)
{
this.type = type;
}
}
public class Foo : Base
{
public Foo() : base(0) {}
}
public class Bar : Base
{
public Bar() : base(1) {}
}
If you just want something to identify the dynamic (most-derived) type of the object passed in, that's built into .NET, via the Object.GetType() method.
public static void printType(Base b)
{
Console.WriteLine(b.GetType().Name);
}
Of course, this isn't quite the same as having attached data under your control. You can, however, use a Dictionary<Type, T> to associate data of arbitrary type with the various subclasses. It would be reasonable to use the subclass type initializer to install new entries into such a dictionary.
public class Base
{
static internal readonly Dictionary<System.Type, int> TypeMap =
new Dictionary<System.Type, int>();
}
public class Foo : Base
{
static Foo { TypeMap.Add(typeof(Foo), 0); }
}
public class Bar : Base
{
static Bar { TypeMap.Add(typeof(Bar), 1); }
}
public static void printType(Base b)
{
Console.WriteLine(Base.TypeMap[b.GetType()]);
}
This WILL be a bit slower than the field-per-object method, however it doesn't add any extra storage per-object.
I need a way to create a static class where some constants can be case specific, but hard-coded.
What I really want to do is have a class where several constants are provided when the class is extended - I want the 'constants' hard-coded. I figured I will make the some abstract properties and define the get { return constant; } when extending the class.
I know that is not possible, so now I am facing two options and am wondering what would be best and why (if there are options I'm missing please let me know!)
Create a static class with nullable fields and throw an exception if the fields are null when the static method is called.
Give up the static class. Have a non-static class with abstract properties and create an instance of the object wherever I need it even though all the functionality really is static.
I know this might be subjective and case-dependant, however I am going around in circles when thinking about this and could really do with some external input. That plus I hope there might be away of doing what I want and I'm just thinking about this wrong.
Update: Code: I will try to write some code that describes what I'd like to accomplish. I know this code can't work!
Imagine that the abstract class Calculation is in a dll, used by many projects. The functionality is the same for all of them, just the Constant varies from project to project.
public abstract static class Calculation
{
private abstract int Constant { get; } //The constant is unknown at this time
public static int Calculate(int inputValue)
{
return inputValue * Constant;
}
}
The class Calc is defined in a separate project where the functionality is needed and the Constant is known.
public static class Calc : Calculation
{
private override int Constant { get { return 2; }
}
...
static class Program
{
[STAThread]
static void Main()
{
//At some point:
int result = Calc.Calculate(6);
}
}
I suppose the simplest way would be to create a non-static class and create an instance, however I fear having several instances of the class could be expensive and would like to prevent that if possible.
I can't see how I could write this as a singleton pattern without writing it again in each project - having only the Nested class in the dll. That doesn't prevent the implementor to just create an ordinary class and is likely to restart the debate for every project where the code is used.
Update #2 : What I ment with option one is this:
Class in a dll:
public static class Calculation
{
public int? Constant {get; set;}
public static int Calculate(int inputValue)
{
if (Constant == null)
throw new ArgumentNullException();
return inputValue * (int)Constant;
}
}
Usage of the function in a seperate project:
static class Program
{
[STAThread]
static void Main()
{
//At some point:
Calculation.Constant = 2;
int result = Calc.Calculate(6);
}
}
Option one is very simple and elegant, what bothers me about it that nothing forces the implementor to set the Constant. I fear an (admittedly unlikely) scenario where an obscure corner case will cause the property to not be set and for the code to fail (and Constant beeing the last suspect)...
You could make non-static classes that follow singleton, ensuring only one instance of the object ever to exist. I guess that could be the next best thing.
You can't want static and inheritance at the same time ! It simply does not make sense !
If you need to override behavior, you need inheritance !
If you want simplicity of call (one of the advantage of statics), you can use Factory (or singleton if only one instance is needed)
My guess is that you probably have to rethink your model. This set of constants of yours probably represent something that you could extract in a separate class then pass this class to your static method. Would that fit your needs ?
Edit
To your code sample:
public abstract static class Calculation
{
public static int Constant { get; set; }
public static int Calculate(int i) { return i * Constant; }
}
// ...
Calculation.Constant = 6;
Calculation.Calculate(123);
Somewhat more general:
public abstract static class Calculation
{
public struct Context
{
public int Constant, SignificantDigits;
public bool Radians;
}
public static int Calculate(int i, Context ctx) { return i * ctx.Constant; }
}
// ...
Calculation.Calculate(123, new Calculate.Context { Constant = 6 });
First idea:
The closest I can think of is generics:
public interface ISpecifics
{
void DoSomething();
string SomeProp { get; }
}
public static class Static<S>
where S : ISpecifics, new()
{
public static string ExerciseSpecific()
{
var spec = new S();
spec.DoSomething();
return spec.SomeProp;
}
}
Or if you really need a single static type
public static class Static
{
public static string ExerciseSpecific<S>()
where S : ISpecifics, new()
{
var spec = new S();
spec.DoSomething();
return spec.SomeProp;
}
}
Does that help?
I needed pretty much the same thing, so first I made a non-static class with all the functionality.
Then, a static class which instantiates one such non-static class in its static constructor.
Then any of the static methods calls the respective instance methods.
Something like this:
public class CalculationInstance
{
private int constant;
public int Calculate(int inputValue)
{
return inputValue * constant;
}
public void AnyOtherMethod()
{
....
}
public CalculationInstance(int constant)
{
this.constant=constant;
}
}
public static class Calculation
{
const int CONSTANT=2;
private CalculationInstance calc;
static Calculation()
{
calc=new CalculationInstance(CONSTANT);
}
public static int Calculate(int inputValue)
{
return calc.Calculate(inputValue);
}
public static void AnyOtherMethod()
{
calc.AnyOtherMethod();
}
}
static class Program
{
[STAThread]
static void Main()
{
//At some point:
int result = Calculation.Calculate(6);
}
}
I feel this doesn't make sense here, a static class is by default sealed class which means it is sealed for inheritance. So please don't consider having static with abstract.
You can have an abstract class and the child class can inherit and override the methods.
Background: I have enclosed (parent) class E with nested class N with several instances of N in E. In the enclosed (parent) class I am doing some calculations and I am setting the values for each instance of nested class. Something like this:
n1.field1 = ...;
n1.field2 = ...;
n1.field3 = ...;
n2.field1 = ...;
...
It is one big eval method (in parent class). My intention is -- since all calculations are in parent class (they cannot be done per nested instance because it would make code more complicated) -- make the setters only available to parent class and getters public.
And now there is a problem:
when I make the setters private, parent class cannot acces them
when I make them public, everybody can change the values
and C# does not have friend concept
I cannot pass values in constructor because lazy evaluation mechanism is used (so the instances have to be created when referencing them -- I create all objects and the calculation is triggered on demand)
I am stuck -- how to do this (limit access up to parent class, no more, no less)?
I suspect I'll get answer-question first -- "but why you don't split the evaluation per each field" -- so I answer this by example: how do you calculate min and max value of a collection? In a fast way? The answer is -- in one pass. This is why I have one eval function which does calculations and sets all fields at once.
You could declare inside E a private interface IN, explicitly implemented by N. This interface would expose the members of N accessible only by E :
public class E
{
public void Foo()
{
IN n = new N();
n.Field1 = 42;
}
public class N : IN
{
private int _field1;
int IN.Field1
{
get { return _field1; }
set { _field1 = value; }
}
}
private interface IN
{
int Field1 { get; set; }
}
}
If it's possible for you to put the parent and child classes in another assembly, you can make use of internal for the setters. That's generally how this is dealt with in the wild.
EDIT:
Thomas Levesque's answer gave me an idea:
class Program
{
static void Main(string[] args)
{
E myE = new E();
Console.WriteLine("E.N1.Field1 = " + myE.N1.Field1);
Console.WriteLine("E.N2.Field1 = " + myE.N2.Field1);
}
public interface IN
{
int Field1 { get; }
}
public class E
{
private N _n1 = new N();
private N _n2 = new N();
public E()
{
_n1.Field1 = 42;
_n2.Field1 = 23;
}
public IN N1
{
get { return _n1; }
}
public IN N2
{
get { return _n2; }
}
private class N : IN
{
private int _field1;
public int Field1
{
get { return _field1; }
set { _field1 = value; }
}
}
}
}
Depending on how you need to expose the child class N, this could work.
Another alternative is to leave the members you wish to be private public if your (nested) class is private. If fields of private class is public, its only going to be exposed to the enclosing class.
public class E
{
public void Foo()
{
IN n = new N();
n.field1 = 42;
}
class N : IN
{
public int _field1;
}
}
Now N is only visible to E, so n._field1 being public only matters to E, and you're safe..
This is an old question, but here goes a possible solution that doesn't use interfaces.
You can have a static function in the inner class which sets up delegates in the outer class, like so:
public class Outer {
private delegate void _operateDlg(Inner inner, bool value);
private static _operateDlg _validate;
static Outer() {
Inner.Init();
}
public void Set(Inner inner, bool value) {
_validate(inner, value);
}
public class Inner {
public bool IsValid {get; private set; }
public static void Init() {
Outer._validate += delegate(Inner i, bool value) {
i.IsValid = value;
};
}
}
}
You can put all kinds of different delegates in the outer class that you assign with the Inner.Init() method, such as methods which return an instance of the Inner class through a private constructor or getters/setters of a particular field.
If you don't mind having an extra Init() static function in your inner class, then this doesn't have to change. But if you don't want the Init() method to be visible, you can use reflection to call it:
using System.Reflection;
public class Outer {
private delegate void _operateDlg(Inner inner, bool value);
private static _operateDlg _validate;
static Outer() {
typeof(Inner).GetMethod("Init",
BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
}
public void Set(Inner inner, bool value) {
_validate(inner, value);
}
public class Inner {
public bool IsValid {get; private set; }
private static void Init() {
Outer._validate = delegate(Inner i, bool value) {
i.IsValid = value;
};
}
}
}
I know that one could use Reflection to bypass private access restrictions anyway, but using it just to call one single Init() method which then assigns the appropriate delegates is a much cleaner and more versatile solution in my opinion. The alternative would be calling reflection for every single delegate you might want to create, and even then there could be limitations (such as the inability to create delegates to constructors).
The above solution not only supports wrapping constructors, but it will only use Reflection once in the lifetime of a program, so there shouldn't be a noticeable performance penalty other than the fact that you're using delegates to achieve what should have been allowed as direct access in the first place. I don't know why C# doesn't support this, and I can't think of a good reason why it doesn't.
make the fields "protected internal"
if the nested classes are private you could use obly "internal" to those fields.