Why this works in C# (generic class and self-reference)? - c#

I have
class X<T> : Base
{
//For exemple:
static T something();
}
And I can have
class A : X <A>
{
}
To logically have something like this:
class A : Base
{
static A something();
}
This works and works well.
But in my comprehension, it's kind of self-reference (A is the children of X, while X doesn't exists before A...), which is breaks the foundation of computer science, so I want to know what's wrong with my comprehension??

It's totally fine. You can do similar without generics too:
class Test
{
public static Test GetInstance()
{
return new Test();
}
}
I don't see any self-reference here. And actually it's quite useful pattern e.g. when implementing singletons. Simplified concept (I know, it should use locks, etc...):
public static class Singleton<T> where T : new()
{
private static T _instance;
public static T GetInstance()
{
return _instance ?? (_instance = new T());
}
}
Edit - Answering your comment question:
X<T> already exists for all suitable T parameters. By suitable I mean every type that suits generic constraint (or just every type when there is no constraint). And by every I mean not only all classes available within your assembly. Just every suitable type.
Generic class/method is just a template which is resolved for given particular generic type in runtime. That's why you don't have to even use the generic class at all in assemble it's declared within. And that's why your code works fine.

Related

Class<T> and static Class, Best Practices?

I have a scenario that (simplified) is as follows:
public static class Example
{
public const int CONSTANT_VALUE = 1;
public static Example<T> Create<T>(IEnumerable<T> argument)
where T : class
{
return new Example<T>(argument);
}
//More overloads of Create<T>, possibly other static methods, etc..
}
public class Example<T>
where T : class
{
public Example(IEnumerable<T> argument)
{
//Do Stuff
//Nothing like this in the real code, just example
//that constants are used from the other class.
if (something == Example.CONSTANT_VALUE)
{
//Do A Thing
}
}
//Lots more code
}
The basic idea is that I can have static methods, constants, etc. available through the name of the class through the static class, while the actual implementation is in the type-argumented non-static class.
My question is whether or not this is a good way to set this up. Is there a way to put some static methods and constants that don't care what the type argument is on Example<T>? Is there otherwise a more recommended pattern? What I have works fine, but I wanted to know if there are other ways since this is the first time I've ended up doing something like this (not that it's conceptually new to me, just never had need).
This would only make sense if the constants are public. If they are only for internal use inside Example<T> then this is pointless, becuase you can reference them without a fully qualified name.
If the constants are of public use, I wouldn't use this pattern anayways; Example and Example<T> are two different classes, it is potentially confusing to any user, and not immeadiately obvious, that constants defined in the non generic class are aplicable to the generic one.
You are only avoding the user a few keystrokes, I'm not really sure it is worth it.
Update: other options
In this scenario, I'd use the following factory pattern (assuming the users are outside your assembly)
public class Example<T>
{
internal Example() { } //disallow users from instantiating this class
...
}
public static class Example
{
public const int Constant = ...
public static Example<T> Create<T>() { return new ... }
}
And now all users will interact only with Example and avoid using Example<T>. You could even enforce this with users of your own assembly, you'd just need to make Example<T> a private nested class implementing a public interface:
public interface IExample<T>
{
...
}
public static class Example
{
private class Example<T>: IExample<T> { ... }
public static IExample<T> Create<T>() { ... }
....
}
Unless there is a reason this wouldn't work in your case, I would prefer to use a non-static base class Example, and then let Example<T> inherit from this class. That way you get direct access to all the methods in Example, without having to qualify with the name. Of course, this assumes that the Example class is exclusively to be used in connection with the various typed classes Example<T>.

How does c# handle nested (generic) types?

I'm trying to understand how C# views types in the face of nesting.
More specifically I'm trying to understand why some types are not considered assignment compatible or even castable, when there "kind of" only exist one definition of the nested class. Does the compiler / CLR actually generate different types for these, or what rules are at play exactly...
Example code:
public class Foo<T>
{
protected class Private2 : Private1<Foo<T>>
{ }
protected class Private1<T2> where T2 : Foo<T>
{
public sealed class Nested
{
public void Test(T2 foo)
{
foo.Method2(this); //Nope!
var nes = (Private2.Nested)this; //Nope!
}
}
}
public void Method1()
{
var nested = new Private2.Nested();
nested.Test(this);
}
private void Method2(Private2.Nested nested)
{
// something code...
}
}
So even though the nested instance is created as a Private2.Nested it can not be casted to that type. And... well... how do the different Nested types relate to each other given that Nested is in fact sealed? (They can't be inheriting from each other right? But on the other hand their implementation should be 100% identical... am I wrong?)
Primary question: What exactly is the compiler doing when it "compiles" this nested class?? How many unique types (excluding valuetype-related) are actually generated, and if it is all the "same" type, is the restriction artificial (as in wouldn't an unsafe cast actually work)? (What I'm saying is that the IL for all these types comes from the same code definition - so at some level the compiler must know. Are instances of these types not bit-for-bit identical apart from their type-names?)
Secondary question: not what I'm really asking here, mostly for brevity / context: is there some simple change that would make the above work? Am I missing something obvious?
The type Foo<T> must never be directly referenced inside Private1<T2> - only use of T2 is allowed. Foo<T> is just my example stand in for nasty generic classes with 10~20 generic types. It's all just a "workaround" for not being able to alias a generic class with its types:
public class Bar<GoodName, OtherName, Readability, NopeMr, DontThinkSo, Suffering, Dispair>
{
//If only this was real...
using BarT = Bar<GoodName, OtherName, Readability, NopeMr, DontThinkSo, Suffering, Dispair>;
public void Method1(BarT bar) { ... } //so good!!
//goodbye readability... see you never...
public void Method2(Bar<GoodName, OtherName, Readability, NopeMr, DontThinkSo, Suffering, Dispair> whatIsThisVariable) { ... }
}
Purpose: To avoid types of fields and method-parameters that are several screens wide and utterly unreadable! >:(
...As a side note I really wished this could be used as a type inside classes and interfaces, as in Private2 : Private1<this>. Well ok, that wouldn't work because it collides with extension syntax on methods, but something similar, perhaps <this>, <super>, <base> used like Method(<this> arg) or Private2 : Private1<<super>> ... kind of weird maybe.
Consider this types:
public class Base {
public static int Value;
public class Nested { }
}
public class Derived:Base { }
What is Derived.Value and Derived.Nested. Actually, when you refer to inherited static members (nested class considered to be static member) thru derived class, you just reference base class members, so this have exactly same meaning as Base.Value and Base.Nested at compile time. There are no separate static field Derived.Value or separate class Derived.Nested.
public static void Test() {
Derived.Value=10;
Console.WriteLine(Base.Value);
Base.Value=20;
Console.WriteLine(Derived.Value);
Base.Nested bn=new Derived.Nested();
Derived.Nested dn=new Base.Nested();
Console.WriteLine(typeof(Base.Nested).FullName);
Console.WriteLine(typeof(Derived.Nested).FullName);
Console.WriteLine(typeof(Base.Nested)==typeof(Derived.Nested));
}
Original answer:
Foo<A>.Private1<B>.Nested and Foo<C>.Private1<D>.Nested considered to be different types if A!=C or B!=D. They can share same implementation internally, but for assignment compatibility they are different. Foo<T>.Private2.Nested is just alias to Foo<T>.Private1<Foo<T>>.Nested. And even if class Bar:Foo<A>{}, classes Foo<A>.Private1<Foo<A>>.Nested and Foo<A>.Private1<Bar>.Nested still considered to be different types. So Foo<T>.Private1<T2>.Nested can not be converted to Foo<T>.Private1<Foo<T>>.Nested as T2 is not necessary Foo<T>.
You're not thinking with portals. Your inner classes are already generalized on T.
public class Foo<T>
{
private class Private2 : Private1
{ }
private class Private1
{
public sealed class Nested
{
public void Test( Foo<T> foo )
{
foo.Method2( this ); //Yup
var nes = (Private2.Nested)this; //Yup
}
}
}
public void Method1()
{
var nested = new Private2.Nested();
nested.Test( this );
}
private void Method2( Private2.Nested nested )
{
// something code...
}
}
Partial answer to the primary question:
It was bugging me that you can make the code compile by changing Method2 to accept an object and cast it at runtime, because the nested instance is of the correct type (it's instantiated inside Method1). That would seem to work - as long as Foo is sealed - but as soon as someone else can subclass Private1 it is no longer guaranteed to work. (And thus not a solution.) However testing this approach reveals:
Private2.Nested is only a construct of syntax rules - using GetType() on the resulting variable says Private1.Nested and there is no Private2.Nested type.
I think the irksome feeling I was getting from this (and why I concidered sealed to be related) was some kind of confusion on my part when it came to distinguishing between subtype and inheritance. Because the outer classes are inheriting (Private1 and Private2) it feels like inheritance, and thus it feels like it should somehow be castable. But if I understand this correctly they are merely of the same subtype:
There need not be and is in fact no inheritance relation one way or the other (as the sealed clearly hints) because "the inheritance hierarchy is distinct from from the subtype hierarchy", and thus a downright conversion would be needed (since casts are bound to the inheritance hierarchy).

How can I ensure that a class has just 1 constructor in .NET?

Well my question is pretty self-explanatory. I have a class and I want to ensure that there is just 1 public constructor to this class. Moreover, I also want to ensure that the constuctor should have just 1 parameter. My class will be modified by many different developers, and I am looking for a way to ensure that they do not write any more constructors than are currently specified. Is it possible? If yes, then how?
Note, my class inherits from another class which currently does not have any constructor but it might have in the future. I don't know if this information will affect the answer or not but just thought of adding it.
Please help!
Thanks in advance!
You could consider writing a unit test to encode this design constraint. As long as the test isn't fiddled with, this will warn when the contraint is broken.
This would be a good case for a nice comment in your class detailing this constraint.
The following testing approach can be expanded to provide a test which could test derived types, rather than a single type. This approach is a type of static analysis, and removes the overhead that would be incurred by expensive runtime checking through reflection for instance. A test ensures that the design constraint is validated at build time, rather than at runtime which could be after code is released.
[Test]
public void myClass_must_have_one_single_paramter_ctor()
{
Type type = typeof(MyClass);
const BindingFlags Flags = (BindingFlags.Public | BindingFlags.Instance);
ConstructorInfo[] ctors = type.GetConstructors(Flags);
Assert.AreEqual(1, ctors.Length, "Ctor count.");
ParameterInfo[] args = ctors[0].GetParameters();
Assert.AreEqual(1, args.Length, "Ctor parameter count.");
Assert.AreEqual(typeof(string), args[0].ParameterType, "Ctor parameter type.");
}
public class MyClass
{
public MyClass(string woo) {}
}
All classes have one constructor. If you don't specify one in the source code, the compiler will add an empty public constructor - the equivalent of:
public class MyClass
{
public MyClass()
{
}
}
However if you specify at least one constructor in the source, only the constructors that you explicitly specify will be created, e.g. the following class has one public constructor that takes a single string parameter:
public class MyClass
{
public MyClass(string myParameter)
{
...
}
}
In short, there's nothing special you need to do. If you only want one public constructor then ... just write one public constructor.
Only the person who codes the class can restrict the number and type of constructors.
So if that is you, then you can just code it the way you want.
This could be achieved using reflection. The only thing you need to take care is, the base class code shouldn't be accessible to or editable by developers.
class Program
{
static void Main(string[] args)
{
Inherited obj = new Inherited("Alpha");
obj.test();
Inherited1 obj1 = new Inherited1(); //This will fail as there is no ctor with single param.
obj1.test();
}
}
public class MyBase
{
private static IList<string> ValidatedClasses = new List<string>();
public MyBase()
{
if(!ValidatedClasses.Contains(this.GetType().FullName) &&
!ValidateConstructorLogic())
{
throw new ApplicationException("Expected consturctor with single argument");
}
}
public bool ValidateConstructorLogic()
{
bool ValidConstFound = false;
foreach (var info in this.GetType().GetConstructors())
{
if(info.GetParameters().Length ==1)
{
lock (ValidatedClasses)
{
ValidatedClasses.Add(this.GetType().FullName);
}
ValidConstFound = true;
}
}
return ValidConstFound;
}
}
public class Inherited:MyBase
{
public Inherited(string test)
{
Console.WriteLine("Ctor");
}
public void test()
{
Console.WriteLine("TEST called");
}
}
public class Inherited1 : MyBase
{
public void test()
{
Console.WriteLine("TEST called");
}
}
You could use FxCop to validate your code against a set of predefined rules. I beleive this might be the apt solution to your problem. If you need help on creating custom FxCop rules, please refer this article.
Constructors are not inherited from base classes.
Your class will have only the constructors that you write, except for (as others have pointed out) a default public constructor that is generated by the compiler when you do not explicitly provide one of your own.
You could try using a nested builder, as described by Jon Skeet. Basically: You force the user to go through the builder which then calls the private class constructor. Since the class constructor is private, only the nested builder has access to it.
Alternative: Use static factory methods, make the constructor private & document your intentions.
Based on your comments, I don't think this is a "coding" problem. This is a policy & enforcement problem. You don't want other developers in your team creating more constructors.
In that case, go tell them that. Whoever is in charge of your source code repository can enforce it by rejecting changes that break the policy. Adding code to deal with this is just going to add runtime penalties to users for no reason.

C# generic factory method

Perhaps this is a simple newbie C# question, but so be it---it will be a fresh break from my other questions, which are so difficult that no one knows the answer to them. :)
Let's say I have a generic type in C#:
Thing<T>
And let's say I want to make a thing using a static factory method. In Java, this is no problem:
public static <T> Thing<T> createThing()
{
return flag ? new Thing<Integer>(5) : new Thing<String>("hello");
}
How do I do this in C#? Thanks.
If you want to return an instance of a templated class using one of many different template arguments, one way to do it is with an abstract base (or an interface):
abstract class UntypedThing { }
class Thing<T> : UntypedThing
{
public Thing(T t) { }
}
class Foo
{
public static UntypedThing createThing(bool flag)
{
if (flag)
return new Thing<int>(5);
else return new Thing<String>("hello");
}
}
The UntypedThing class would contain as much code as possible that does not rely on the template type. The Thing class would ideally only contain code that relies on the template type. The factory class Foo always returns the former.
You can in theory use reflection to build up the correct generic type, but it will be pretty useless to you as at some point you will need to upcast it to a less specific type.
public class ThingFactory {
public object Create(bool flag) {
Type outputType = null;
if(flag) {
outputType = typeof(string);
} else {
outputType = typeof(int);
}
return Activator.CreateInstance(typeof(Thing<>).MakeGenericType(outputType));
}
}
As you can see, the value of doing this is about zero as you will need to cast the return type to the type you want, meaning that the logic to determine it needs to live outside the Create method.
I would use Reinderien's method and have a non-generic base. This is the most sane and idiomatic approach.
Oh, the trouble I get myself in when I simply try to do something simple.
It turns out that C# 4 allows this sort of covariance---sort of. First, I have to make Thing an interface and specify the "out" generic parameter:
public interface Thing<out T> {...}
But if I do certain things, C# won't let me use covariance. For example, if I try to return T from the interface:
public interface Thing<out T>
{
public T GetT();
Even if I manage to get covariance with Thing, what do I do with it?
Thing<object> thing=createThing();
The compiler tells me that the type cannot be inferred from usage.
Let's say I say screw the whole T thing and make the factory method return Thing of type object:
public static Thing<object> createThing() {...}
Fine, but now where do I put it?
IList<Thing<object>> list=new List<Thing<object>>();
Thing<object> thing=createThing();
list.Add(thing);
Yes, I have to say that this is a list of Thing with T of type Object, because C# has no wildcard type.
If this were Java, I'd simply say:
public class Thing<T> {...}
public static <T> Thing<T> createThing() {...}
List<?> things=new ArrayList<Thing<?>>();
Thing<?> thing=createThing();
things.add(thing);
If I wanted extra safety by saying that T had to be of a special type, I'd say:
public static <T extends MyBaseType> Thing<T> createThing() {...}
List<? extends MyBaseType> things=new ArrayList<Thing<? extends MyBaseType>>();
Thing<? extends MyBaseType> thing=createThing();
things.add(thing);
Then I'd figure out what T is later, when I had more information.
This all seems to come down to incomplete generic covariance in C# coupled with the lack of C# generic wildcards. (I still maintain it isn't an erasure issue.)
So what do I do? The only simple thing to do seems to follow Reinderien's answer and split out a non-generic base class.
(I wonder if in this non-generic base class I could have object getValue() and then use covariance in the subclass to return T getValue()? Ack, I'm tired of this---I'll leave that for another day.)

Deriving static members

I have a base class that has a private static member:
class Base
{
private static Base m_instance = new Base();
public static Base Instance
{
get { return m_instance; }
}
}
And I want to derive multiple classes from this:
class DerivedA : Base {}
class DerivedB : Base {}
class DerivedC : Base {}
However, at this point calling DerivedA::Instance will return the same exact object as will DerivedB::Instance and DerivedC::Instance. I can solve this by declaring the instance in the derived class, but then every single derived class will need to do that and that just seems like it should be unneccessary. So is there any way to put all this in the base class? Could a design pattern be applied?
There's one really icky way of doing this:
class Base
{
// Put common stuff in here...
}
class Base<T> : Base where T : Base<T>, new()
{
private static T m_instance = new T();
public static T Instance { get { return m_instance; } }
}
class DerivedA : Base<DerivedA> {}
class DerivedB : Base<DerivedB> {}
class DerivedC : Base<DerivedC> {}
This works because there's one static variable per constructed type - e.g. List<string> is a different type to List<int> and so would have separate static variables.
I've taken the opportunity of making it an instance of the derived class as well - I don't know whether that's what you want or not, but I thought I'd at least make it available for you :)
In general though, this is a nasty thing to do. Static variables aren't really designed for this kind of use - I've just abused a feature of generics to get "sort of" the behaviour you asked for.
Also note that Base<DerivedA>.Instance will return the same result as DerivedA.Instance - the property/variable don't "know" that you're using DerivedA.Instance. I don't know whether or not that's important to you.
With the extra non-generic class, you can write:
Base t = DerivedA.Instance;
t = DerivedB.Instance;
If you don't need that, take it out :)
Static methods does not support polymorphism, therefore, such a thing is not possible.
Fundamentally, the Instance property has no idea how you're using it. And a single implementation of it will exist, as it's static. If you really wanted to do this, this "not recommended" solution is available (I got the idea from Jon's solution):
private static Dictionary<Type, Base> instances = new Dictionary<Type, Base>();
public static T GetInstance<T>() where T : Base, new() {
Type ty = typeof(T);
T x;
if (instances.TryGetValue(ty, out x)) return x;
x = new T();
instances[ty] = x;
return x;
}
Short answer: not that I'm aware of. Static members are always nonvirtual and do not readily support polymorphism.
However, you should also ask yourself why you are doing this. Normally, static members are shared resources that every instance of that class (including the derived classes) will find useful. However, when you make a static instance, you are usually building towards a singleton pattern. In this case, you usually want to seal the class so you can't have derived classes, thus rendering the entire point moot. Thus, you should really be analyzing why you are wanting to do this and solve that problem instead.

Categories

Resources