Chris
Tu-Thach
>.
>
The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation. For example, if you had
the following:
public abstract class Base
{
public static abstract void DoSomething();
}
Then you had a derived class like this:
public class Derived : Base
{
public static override void DoSomething()
{}
}
How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.
In order to get around this now, you should use a class factory pattern
combined with a singleton pattern. The singleton pattern is used to mimic
static behavior, while the class factory pattern is used to indicate the
derived type to use (while returning the base type).
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- nicholas...@exisconsulting.com
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:%23h4xIX8...@tk2msftngp13.phx.gbl...
Look at the topic 'Static variables and inheritance'
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:#h4xIX8c...@tk2msftngp13.phx.gbl...
> How would you indicate that you want to use the implementation in
> Derived? I can have many implementations of DoSomething, and if I want to
> call through the Base class, there is no way of indicating which derived
> class to use.
Fair enough. But I see having an abstract static member as more of a way to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:
public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}
public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}
Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:
public abstract class ImporterBase {
//stuff from above definition
public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}
Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.
But then, I can just use attributes.
Chris
The reason is simple.
A virtual method is one whose implementation is selected on the basis of the
type of the object on which it is called. Static methods are not called on
an object, therefore that sort of determination cannot be made.
What you may be after is what might be called a 'contract' rather than an
interface. This isn't available in C#. There's quite a lot of discussion on
that in another thread, under the title of 'Re: C# language feature
proposal' on this newsgroup, dated 1/9/03.
Regards,
Jasper Kent.
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:%23h4xIX8...@tk2msftngp13.phx.gbl...
public abstract class ImporterBase {
protected abstract static string[] ExtensionsSupported {get;}
...
public class CsvImporter : ImporterBase {
protected static override string[] ExtensionsSupported {
...
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:ek77iN9...@tk2msftngp13.phx.gbl...
On line 3 of ImporterBase.GetImporter it should read
if (t.IsSubclassOf(typeof(ImporterBase))) {
Sorry.
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:ek77iN9...@tk2msftngp13.phx.gbl...
B\rgds
100
"grmAbay" <grm...@hotmail.com> wrote in message
news:O2XuYL9...@TK2MSFTNGP11.phx.gbl...
In a previous thread, these reasonings were given as well. My believe
is that unless you can achieve polymorphism, then you shouldn't introduce a
new language construct like this which will need additional support through
another mechanism. Abstract already has a very well-defined meaning, and
that meaning would be diluted though this use of it.
If you have to resort to reflection anyways to do this, then you can
easily get around this by creating a custom attribute and applying it to the
static method that you want to represent your "overridden" method in another
class. Also, I think that using the design patterns pointed out represent a
very clean solution to the issue as well. Having to use a language
construct in conjunction with reflection is rather dirty. If I had to use
reflection to call overridden methods on derived classes, I don't think that
I would like it too much.
--
- Nicholas Paldino [.NET/C# MVP]
- nicholas...@exisconsulting.com
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:ek77iN9...@tk2msftngp13.phx.gbl...
I dont see any reason to have this abstract member in the base class. You
will get the right value anyway.
Since you have the Type object to some class
(string[])t.GetProperty("Extension").GetValue(null, null); will get the
property's value of this class regardless of whether you have defined that
abstract method in the base class or not.
B\rgds
100
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:ek77iN9...@tk2msftngp13.phx.gbl...
Could you rough out how to apply the singleton/class factory pattern to my
scenario? How would I use these methods to make sure that every class
derived from ImporterBase provided the extensions that it can import? Keep
in mind that in my situation, I'm loading these implementations of
ImporterBase from assemblies located at runtime, like this:
string[] files = Directory.GetFiles(Environment.CurrentDirectory,
"*company.Application.Importer*dll*");
foreach (string s in files) {
Assembly a = Assembly.LoadFile(s);
//etc
}
Right now I use attributes, like this:
[AttributeUsage(AttributeTargets.Class)]
public class ExtensionsAttribute : Attribute {
public readonly string[] Extensions;
public ExtensionsAttribute(string[] extensions) {
Extensions = extensions;
}
}
[Extensions(new string[] {"csv"})]
public class CsvImporter : IssueImporter {
...
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(ImporterBase))) {
ExtensionsAttribute[] exts =
(ExtensionsAttribute[])t.GetCustomAttributes(typeof(ExtensionsAttribute),
false);
if (exts.Length > 0)
foreach (string e in exts[0].Extensions)
if (e == extension)
return (ImporterBase)Activator.CreateInstance(t);
}
}
Would your class factory/singleton patterns provide a better way to do this?
Chris
"Nicholas Paldino [.NET/C# MVP]" <nicholas...@exisconsulting.com> wrote
in message news:ualDFY9c...@TK2MSFTNGP10.phx.gbl...
You can't have polymorphism via reflection.
Consider this:
Case 1:
Type t = someObject.GetType();
In MSDN we can read the following for Object.GetType method:
"
....
Return Value
The Type instance that represents the exact runtime type of the current
instance.
.....
"
So polymorphism can't play any role here because we are going to call the
methods of the *actual* run-time type.
Well, we can get a type object for one of the parent classes and try to call
say
Type t = typeof(ABaseForSomeObjectsClass)
t.GetProperty("PropName").GetValue(someObject,.....);
And to say that we really need polymorphism here. It doesn't make sence,
though. Since we have the reference to the object we always can call:
someObject.GetType() to get the right type object. And we are back to square
one.
Case2:
Type t = typeof(SomeType);
If we need to access instance method we need to have reference to the actual
object. You already have my *Case1*...
If we we want to use a static member.... Well, we have already specified
the type. There is no room for polymorphism again. Mainly because we don't
have an object that has a *real* type.
And to back up my point here there is some example of this.
//I assume here that *static abstract* exist
class Base
{
public abstract static void Foo();
}
class Derived1: Base
{
public override static void Foo()
{
....
}
}
class Derived2: Base
{
public override static void Foo()
{
....
}
}
Somewhere in the code
Type t = typeof(Base)
So now, if we try to call Foo via reflection, which one should be called
Derived1.Foo or Derived2.Foo?
In this case polymorphism is not possible again.
Any other way to obtain a type object belongs to one of those two cases I
believe.
The real problem is that Type objects *represent* tha given type. They are
not references to actual meta-type objects (which in fact exist internally)
B\rgds
100
"Nicholas Paldino [.NET/C# MVP]" <nicholas...@exisconsulting.com> wrote
in message news:ualDFY9c...@TK2MSFTNGP10.phx.gbl...
There wasn't an implication that you can have polymorphism through
Reflection, but rather, to gain the polymorphism on static members, you
would have to use a combination of reflection and the abstract keyword.
--
- Nicholas Paldino [.NET/C# MVP]
- nicholas...@exisconsulting.com
"100" <1...@100.com> wrote in message
news:u$%23IKD%23cDH...@tk2msftngp13.phx.gbl...
The singleton pattern would assure that only one instance of an object
exists. You would set the boundaries of this limitation to the app-domain,
which is simple, because your singleton will be stored in a static member.
So, you define your base class or interface which has the methods you
want to expose (the static ones, but it will be exposed through a singular
instance, which is the equivalent of static), like this:
public interface IMyInterface
{
void DoSomething();
}
Or, you could make it a base class or abstract class, it doesn't matter,
as long as you have a type that is extensible.
Then, you would implement the interfaces/abstract classs wherever you
wish. Once you have that, you would have a class factory, which would be
implemented as a static method somewhere.
public class MyClassFactory
{
// Have a hashtable which will have the instances that have been
created.
private Hashtable sobjInstances = new Hashtable();
// Will return the singular instance of an object given a key, which you
will supply.
public static IMyInterface GetInstance(object key)
{
// Check for the key in the hashtable. If it doesn't exist, then
// create it and put it in the hashtable.
if (!sobjInstances.ContainsKey(key))
// Create an instance here based on information in the key.
sobjInstances[key] = // Create new instance here.
// Return the value in the hashtable.
return (IMyInterface) sobjInstances[key];
}
}
So, in your case, your key could be the name of an assembly and class
that you know implements the appropriate interface. Of course, you could
use attributes to indicate which classes you should use, but you can use
reflection to scan through all of the types and determine which types
implement which interfaces or derive from which base classes. How much of
this you place into your class factory is up to you.
Using this, you get polymorphism and singular instance (the same as
static) semantics.
--
- Nicholas Paldino [.NET/C# MVP]
- nicholas...@exisconsulting.com
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:%23E72G29...@TK2MSFTNGP09.phx.gbl...
"Nicholas Paldino [.NET/C# MVP]" <nicholas...@exisconsulting.com> wrote
in message news:enaEeD9c...@TK2MSFTNGP11.phx.gbl...
"Nicholas Paldino [.NET/C# MVP]" <nicholas...@exisconsulting.com> wrote
in message news:el6thK%23cDH...@TK2MSFTNGP10.phx.gbl...
To simplify the example I wrote a new one
//The main purpose of the base class is to filter out the types and to
make sure that if Extention property exsits it means excatly what we expect
class Base
{
}
class Derived1: Base
{
//It doesn't need to be public. Anyway if we used anywhere else it can be
public
private static string Extention
{
get{return "CVS";}
}
public Derived1()
{
Console.WriteLine("Derived1 created");
}
}
class Derived2: Base
{
//It doesn't need to be public. Anyway if we used anywhere else it can
be public
private static string Extention
{
get{return "TXT";}
}
public Derived2()
{
Console.WriteLine("Derived2 created");
}
}
class Class1
{
[STAThread]
static void Main(string[] args)
{
//We could load types from file it doesn't really matters.
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach(Type t in types)
{
if(t.IsSubclassOf(typeof(Base)))
{
PropertyInfo prop = t.GetProperty("Extention", BindingFlags.Static
|BindingFlags.NonPublic);
//The class might not define Extention property.
if(prop != null)
{
Console.WriteLine("Type: {0}\n\tExtention: {1}", t.Name,
prop.GetValue(null, null));
Activator.CreateInstance(t);
}
}
}
Console.ReadLine();
}
}
Of course you cannot make sure that every class which inherits from base
will provide Extention property.
Anyway even if we could declare in the base class
abstract static string Extention
{
get;
}
This is not guarantee. I can freely derive a class without implement an
abstract member. The differnce will be that the class will be abstract and
no objects could be created.
B\rgds
100
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:%23E72G29...@TK2MSFTNGP09.phx.gbl...
AspectJ (AOP for Java) allows you among other things to detect and issue
errors at compile time for eg use of public fields, use of console
stdout/stderr, static variables in EJBs, but haven't seen that it can detect
the non existence of something, like a constructor or static method. It can
introduce them, ie plonk a definition inside a class or class hierarchy, or
give default implementations for interface methods, but not the same thing
as simply requiring one to be defined. Don't know if there's an AspectC# or
AspectN equivalent.
"Daniel O'Connell" <onyx...@comcast.net> wrote in message
news:N_66b.367930$Ho3.53743@sccrnsc03...
After doing a bit of research, I found a project called AspectC# [1], going
to dive into the dissertation that backs it later today, not up to that much
reading quite yet.
[1] http://www.dsg.cs.tcd.ie/index.php?category_id=169
This does mean, however, that the specification of requirements is bound
inextricably with its usage. This gives us a couple of advantages:
1) The specification can't go 'over-the-top' asking for requirements that
are never used and therefore wasting implementer's time and causing code
bloat. The C++ template mechanism is very good at not forming instantiations
that can never be called.
2) There is no risk that (as there would be with specification plus
reflection) that at runtime a requirement will be discovered that was
missing from the specification.
Templates give a full list of non-compliance at compile-time. The problem is
that this list is unclear and scattered about the full error list. It might
be useful to develop a tool which strips out all those non-compliances from
the error list and presents a summary of why a class fails to comply. (Some
C++ compilers may already do this.)
Regards,
Jasper Kent.
"Daniel O'Connell" <onyx...@comcast.net> wrote in message
news:N_66b.367930$Ho3.53743@sccrnsc03...
> This does mean, however, that the specification of requirements is bound
> inextricably with its usage. This gives us a couple of advantages:
>
> 1) The specification can't go 'over-the-top' asking for requirements that
> are never used and therefore wasting implementer's time and causing code
> bloat. The C++ template mechanism is very good at not forming
instantiations
> that can never be called.
In the design I want, there would be a few new ways to add functionality
thats not needed, most notably the instance of forcing attributes or
something where the loader doesn't check for them (although the contractual
construct probably would on load aswell...not sure), but nothing that is to
big of a deal. As it stands the biggest problem is when interfaces specify a
method that the external loader never bothers to use.
>
> 2) There is no risk that (as there would be with specification plus
> reflection) that at runtime a requirement will be discovered that was
> missing from the specification.
>
I'm not quite sure what you mean here, part of the goal of this crazy
experiment is to provide a construct that does the reflection nessecery to
verify and return the object specified, to both provide a specification and
to remove the need to write similar reflection code for every plugin or
module loader you write. It wouldn't be too difficult to design a class gen
that produced a factory or something that follows a set of rules and
performs the reflection and a implementing class, that would be my first
goal if I ever get teh design up and moving, but runtime & compiler level
enforcement would be the penultimate.
In the example given, a contract has already been established--in the
form of an abstract class.
I have my own design issue, which brought me to this group in the
first place. I am working on a large number of domain and data mapper
pattern objects. Some of my mappers can handle more than one domain
object, because the domain objects are subclassed.
In order to use a mapper registry (factory) to produce them, I decided
to have each mapper track its mapped types:
public abstract class BaseDataMapper
{
public abstract Type[] MappedTypes{ get ; }
...
}
I think it is reasonable that the author of a mapper should decide
which objects that mapper can map into persistent storage:
public class NamedObjectMapper : BaseDataMapper
{
public override Type[] MappedTypes
{
get{ return new Type[]{ typeof( ServiceType ), typeof(
UnitType ) } ; )
}
}
Now, during registration of the above mapper type in a factory, I need
some way of registering the supported types--from:
mapperRegistry.GetInstanceFor( ServiceType )
I expect the factory to produce the exact mapper I need. Unless the
property described above is also abstract, I cannot do this without
creating an instance of the mapper during registration. Five mappers?
No big deal. Four hundred mappers in a service layer? No way I want
to create an instance of all of those during registration. Not in an
environment where new domain objects and mappers can be added at
runtime, and their types registered.
And this is the thing: attributes? Come on. The issue here is to
force the mapper author to comply with the contract.
So--why not abstract statics?
"Chris Capel" <ch...@ibanktech.comnet> wrote in message news:<#h4xIX8c...@tk2msftngp13.phx.gbl>...
Well, the primary problem is in cases like this, assume Base has a virtual
static called StaticMethod and Derived is derived from Base.
Base b = new Derived();
//this really isn't legal, because you can't access a static method via a
//reference(nor should you be able to, imho).
//even if you could, which StaticMethod is being called here? cases could be
//made that it should be Base.StaticMethod() or Derived.StaticMethod()
//if Derived.StaticMethod() is proper, you could end up with unpredictable
//behaviour here.
b.StaticMethod();
How exactly do you execute the static method without exposing statics (and
some very ugly and troublesome code constructs)? The only way I could think
of currently would be using reflection.
I do not think that there is a technical reason they cannot be added, so
much as a semantic one. Its hard to add such a construct in a way that keeps
the language simple. As such, I don't think it would be a clean thing to add
to the CLR, as it would vastly complicate C# and VB, either by adding a new
keyword(I could see something like staticcall b.StaticMethod() or the like,
its ugly though) or by merging static members into the instance member list,
which is also very ugly. I also do not know what kind of a performance issue
it could be.
I really think a contract construct that can specify attributes and
constructors would provide a better solution, especially as the IDE's
mature.
Although Java unfortunately allows it as syntax, it doesn't use the
type of the instance (or even whether or not it's null) at runtime. In
other words, you can do:
Foo x = new Bar();
x.Something();
and it will call Foo.Something() even if there's a Bar.Something()
method.
--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Currently no lists tracking such a contract exists to my knowledge(nor does
any work on such a one exist, AFAIK). I have floated the idea in various
basic forms here a few times with little more results than things like "That
may be useful" or "I could see how that would work" kind of things. I'm
still considering writing up a full fledged proposal & syntax and posting it
here for comments, but time constraints and reaction to the various ideas
I've posted here havn't pushed me to get on it right away.
I have come to realize that this thread is not exactly the same as what I
was thinking about. This thread, as far as I can tell, is discussing having
"abstract static members" in a class as opposed to having "public static
members" in an abstract class, which you can do. My reasoning behind having
the abstract class with public static functions was to prevent anyone from
creating an unnecessary object from the class. This may not be the best way
of doing what I was after, but it works.
"Chris Capel" <ch...@ibanktech.comnet> wrote in message
news:%23h4xIX8...@tk2msftngp13.phx.gbl...
It works, but that allows the class to be derived from. Perhaps a sealed
class suits you better?
Anyway... I guess sealed is better than abstract. At least another
developer would not be able to change the desired intentions of the class.
"Daniel O'Connell" <onyxkirx@--NOSPAM--comcast.net> wrote in message
news:Uc5kb.583714$cF.254371@rwcrnsc53...
Note that if you just don't provide any constructors at all, a public
parameterless one will be provided for you. You might want to write a
private constructor, which means that nothing else can instantiate it.