473,659 Members | 3,420 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Seriuos monkey business with static generics

I'm puzzled at how static fields intersect with generics, as the
following snippet illustrates.
namespace MonkeyParty
{
abstract class Fruit { }
class Apple : Fruit { }
class Pear : Fruit { }

abstract class Tree<TFruit, TTree>
where TFruit : Fruit, new()
where TTree : Tree<TFruit, TTree>, new()
{
public static TTree TheTree = new TTree();
public TFruit shake() { return new TFruit(); }
}

sealed class Monkey<TFruit> where TFruit : Fruit, new()
{
private sealed class MyFavoriteTree : Tree<TFruit, MyFavoriteTree>
{ }
public TFruit GetFood() { return MyFavoriteTree. TheTree.shake() ; }
public void Eat(TFruit food) { }
}

static class Garden
{
static void MonkeyParty ()
{
Monkey<Apple> Albert = new Monkey<Apple>() ;
Monkey<Apple> Arnold = new Monkey<Apple>() ;
Monkey<Pear> Perry = new Monkey<Pear>();

Albert.Eat(Arno ld.GetFood());
Arnold.Eat(Albe rt.GetFood());
// Perry.Eat(Arnol d.GetFood()); --- compile time error ---
Perry.Eat(Perry .GetFood());
}
}
}
The setup is as follows:

There are two kinds of fruits, each of which grow on a single tree.

So the trees are singletons, and as such, I placed them as
static members of their own class. To allow this, I need a
circular spec, but this seems allright with the compiler.

Then, there are three monkeys, Albert, Arnold and Perry.
Albert and Arnold like apples, Perry likes pears. If you ask
an abe to fetch a fruit, it will go to and shake the tree of its
favourite fruit. Albert and Arnold can feed each other, while
Perry needs to fetch his own fruit and eat it.

Now the docs state that there is only one Tree class -
I quote:

"Generics work a little differently for reference types. The
first time a generic type is constructed with any reference
type, the runtime creates a specialized generic type with
object references substituted for the parameters in the MSIL.
Then, each time a constructed type is instantiated with a
reference type as its parameter, regardless of what type it is,
the runtime reuses the previously created specialized version
of the generic type. This is possible because all references are
the same size."

But if there is only one Tree class, how can it have two differently
typed instances of the same static variable? I mean, can I be
certain that Perry won't unwittingly get an apple because Albert
happened to plant an apple tree in the static variable?

(In case anyone wonders why I made this up: it's a toy model of
an attempt to construct a data model with uniquely represented
constants of various type. The fruits are wrappers for the
constant types, the trees are collections that serve to unify the
fruits, and the monkeys are weak pointer based wrappers for
the fruits (they need to be weakly referenced to allow garbage
collection of non-refernced constants). This is not an accurate
mapping but should give some idea of what I'm trying to do with
statics and generics. Each constant type has its own tree, which
makes the unification simpler.)

Regards/Ole Nielsby
Apr 5 '06 #1
1 1644

Ole Nielsby wrote:
I'm puzzled at how static fields intersect with generics, as the
following snippet illustrates.
namespace MonkeyParty
{
abstract class Fruit { }
class Apple : Fruit { }
class Pear : Fruit { }

abstract class Tree<TFruit, TTree>
where TFruit : Fruit, new()
where TTree : Tree<TFruit, TTree>, new()
{
public static TTree TheTree = new TTree();
public TFruit shake() { return new TFruit(); }
}

sealed class Monkey<TFruit> where TFruit : Fruit, new()
{
private sealed class MyFavoriteTree : Tree<TFruit, MyFavoriteTree>
{ }
public TFruit GetFood() { return MyFavoriteTree. TheTree.shake() ; }
public void Eat(TFruit food) { }
}

static class Garden
{
static void MonkeyParty ()
{
Monkey<Apple> Albert = new Monkey<Apple>() ;
Monkey<Apple> Arnold = new Monkey<Apple>() ;
Monkey<Pear> Perry = new Monkey<Pear>();

Albert.Eat(Arno ld.GetFood());
Arnold.Eat(Albe rt.GetFood());
// Perry.Eat(Arnol d.GetFood()); --- compile time error ---
Perry.Eat(Perry .GetFood());
}
}
}
The setup is as follows:

There are two kinds of fruits, each of which grow on a single tree.

So the trees are singletons, and as such, I placed them as
static members of their own class. To allow this, I need a
circular spec, but this seems allright with the compiler.
My gut instinct is that this is all wrong, but I don't know enough to
be sure. I will leave this for the experts :)

Now the docs state that there is only one Tree class -
I quote:

"Generics work a little differently for reference types. The
first time a generic type is constructed with any reference
type, the runtime creates a specialized generic type with
object references substituted for the parameters in the MSIL.
Then, each time a constructed type is instantiated with a
reference type as its parameter, regardless of what type it is,
the runtime reuses the previously created specialized version
of the generic type. This is possible because all references are
the same size."

But if there is only one Tree class, how can it have two differently
typed instances of the same static variable? I mean, can I be
certain that Perry won't unwittingly get an apple because Albert
happened to plant an apple tree in the static variable?


Different levels. There is only one Tree class at an internal *code*
level; but at the *conceptual* level, Tree<Apple> and Tree<Pear> are
still different classes. A simpler example makes things clear:

class Generic<T>
where T : class
{
public static int i;
}

class Program
{
static void Main(string[] args)
{
Generic<String> .i = 3;

Console.WriteLi ne(Generic<Stri ng>.i);
Console.WriteLi ne(Generic<Arra y>.i);

Console.ReadLin e();
}
}

}

Generic<Array> is a different class from (even though, since T is a
reference type, it will share a code implementation with)
Generic<String> , so we get 3 and 0 output.

--
Larry Lard
Replies to group please

Apr 5 '06 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
3018
by: D Witherspoon | last post by:
I am developing a Windows Forms application in VB.NET that will use .NET remoting to access the data tier classes. A very simple way I have come up with is by creating typed (.xsd) datasets. For example dsParts.xsd and including that in the data tier. I then will create a class that looks like this Public Class CPart Inherits dsParts
10
2307
by: steve bull | last post by:
I have a class SwatchPanel which takes Swatch as a parameter type. How can I call a static function within the Swatch class? For example the code below fails on TSwatch.Exists. How can I get the call to work? Exists is a method within the Swatch class NOT the SwatchPanel class. Is this possible? Suggestions would be very welcome.
10
2233
by: Marc Gravell | last post by:
Given a generic method "of T", is there a good way of ensuring that any static ctor on T has executed? Following code demonstrates (TestClass1) that via generics you can use the Type instance long before the static ctor fires. With a generic class and the "new()" clause, I can force this in the static ctor of the generic class, but this is not always convenient, plus may (possibly?) be seen as a no-op . Sample; ideally I'd get "Static...
7
3248
by: SpotNet | last post by:
Hello NewsGroup, Reading up on Generics in the .NET Framework 2.0 using C# 2005 (SP1), I have a question on the application of Generics. Knowingly, Generic classes are contained in the System.Collections.Generic namespace. Literature I have read on this ties generics in with collections, hence articulate their examples as such. That's fine, I understand what is being said. My question is more towards the application and implementation...
32
1850
by: Martin | last post by:
Hi all, In the following example, I'd like to replace int by a generic. In order word, I would like to replace int by float, double, byte or something like that. I've tried to find a common interface or something like that, but I didn't find. public static int MaxSum(int source) { int maxSoFar = 0, maxEndingHere = 0;
5
2236
by: teel | last post by:
Hi there, I'm trying to apply "less than" and "more than" operators on the Generics (class template-like) type objects. Below is the code of my class representing a parameter that can be any type, but only if it's float or int the comparison results in true/false-like result, else its INVALID. I get error: Operator '<' cannot be applied to operands of type 'T' and 'T' at line: set { m_Value = value < m_MinValue ? m_MinValue : (value >...
6
3279
by: Frank Rizzo | last post by:
I am trying to create a parametrized generic object, but the compiler won't let me. Is this just the way it is? The class has a constraint that says all classes must inherit from BusinessBase, which specifies a parametrized constructor. But c# won't let me do it. public class DataHelper<Twhere T : BusinessBase, new() { public static List<TDataTableToList(DataTable dataTable) { List<TlistOfItems = new List<T>();
3
2725
by: =?Utf-8?B?RnJhbmsgVXJheQ==?= | last post by:
Hi all I have some problems with Crystal Reports (Version 10.2, Runtime 2.0). In Section3 I have added a OLE Object (Bitmap). Now when I open the report in my code I would like to set this OLE Object (load a picture from a given path). Something like this I would expect: _reports.crImage local_Report = new _reports.crImage();
3
1296
by: Anders Borum | last post by:
Hello, I've worked on an API for quite some time and have (on several occasions) tried to introduce generics at the core abstract level of business objects (especially a hierarchical node). The current non-generic implementation is functional, but not as clean as I would like. Although not sure, I believe my problems stem from lacking support of co- and contravariance in C# (which I'm desperately hoping will make it in the next version)....
0
8337
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8748
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8531
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8628
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6181
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5650
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2754
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1978
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.