Why seal a class

M

Michael C

I want to inherit from Bitmap to add a property but I can't because it's
sealed. Is there any reason to seal a class?

Thanks,
Michael
 
M

Maniac

Michael C schreef:
I want to inherit from Bitmap to add a property but I can't because it's
sealed. Is there any reason to seal a class?

Thanks,
Michael

The main purpose of a sealed class is to take away the inheritance
feature so the user can not derive a class from that particular class.
In this way you can seal the boundaries of your application. Normally
it is done with static classes. Structs are always sealed.

The only thing i can think of in this case is that the Microsoft
programmers didn't want any derivation because the Bitmap class
implements the members declared in the Image class. Perhaps that
overriding them could cause problems in other classes.

I hope that this answer gives you all the information that you want.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

It's a design decision , it's an indication that there is no further
inheritance expected for that class.
 
M

Michael C

Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

It's a design decision , it's an indication that there is no further
inheritance expected for that class.

It's a pity, I just want to add some fairly harmless properties like a Tag
property so I can pass some extra info around with the bitmap. It seams to
me that if inheriting the bitmap could cause problems if certain method are
overridden isn't really that big a deal. We can cause all sorts of problems
using the api but we still get to go that :)

Michael
 
G

Guest

There are other way rather than inheritance, for example you can use
aggregation -realizing you own custom Bitmap class and using it everywhere

--
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
M

Michael Bray

It's a pity, I just want to add some fairly harmless properties like a
Tag property so I can pass some extra info around with the bitmap. It
seams to me that if inheriting the bitmap could cause problems if
certain method are overridden isn't really that big a deal. We can
cause all sorts of problems using the api but we still get to go that

While I agree with you in principle and in practice, I can offer the
(obvious?) suggestion to write a class that has a Bitmap as a member, plus
whatever other properties you want to pass around. Then use an instance of
that class in place of Bitmap, and reference the bitmap member when you
want to use the bitmap itself.

-mdb
 
M

Michael C

Michael Bray said:
While I agree with you in principle and in practice, I can offer the
(obvious?) suggestion to write a class that has a Bitmap as a member, plus
whatever other properties you want to pass around. Then use an instance
of
that class in place of Bitmap, and reference the bitmap member when you
want to use the bitmap itself.

That makes sense and is possibly a better solution. What I'm doing is faking
16 bit grayscale bitmaps by using two 8 bit bitmaps as the high and low
order bits. I was hoping to make the low order bitmap a property of the high
order bitmap so that I can can have functions that accept a bitmap as a
parameter check for the low order bitmap.

Michael
 
D

Dave Sexton

Hi Michael,

In .NET 3.0 (shipping with Windows Vista, so I've heard) there are Extender
methods so you can decorate instances of any object or interface with your
own methods and their implementations.

I just thought you might find that interesting. You can download the LINQ
preview for VS.NET 2005 and play around with the up-and-coming functionality
yourself.

I wish it was available for production already 'cause I could sure use LINQ
now.

http://msdn.microsoft.com/data/ref/linq/

- Dave Sexton
 
B

Bruce Wood

Michael said:
I want to inherit from Bitmap to add a property but I can't because it's
sealed. Is there any reason to seal a class?

Supporting the possibility of inheritance--in a published interface
like the .NET Framework--is a lot of work. You have to design your
class's public and protected members with inheritance in mind, ensuring
that anyone inheriting from the class can insert functionality at
useful points, and ensuring that it's reasonably hard to do stupid
things and jackpot one's self while inheriting.

As well, usually, you expose more about the internal workings of your
class and therefore make it more difficult to change in the future,
because the class's contract with the "public" (which now includes
public users and protected inheritors) is stronger.

An example of a badly designed class that supports inheritance is
PrintPreviewDialog, which allows inheritance but has almost every
behaviour / appearance element you could possibly want to modify in a
child class secured as "private". Some writers prefer to simply seal
the class rather than release nonsense like this.
 
M

Michael Nemtsev

Hello Dave,

Take into account that .NET 3.0 is just .NET 2.0 + WinFX, there is no .net
3.0 framework at all.

..net 3.0 is just marketing and nothing else

DS> In .NET 3.0 (shipping with Windows Vista, so I've heard) there are
DS> Extender methods so you can decorate instances of any object or
DS> interface with your own methods and their implementations.
DS>
DS> I just thought you might find that interesting. You can download
DS> the LINQ preview for VS.NET 2005 and play around with the
DS> up-and-coming functionality yourself.
DS>
DS> I wish it was available for production already 'cause I could sure
DS> use LINQ now.
DS>
DS> http://msdn.microsoft.com/data/ref/linq/
DS>
DS> - Dave Sexton
DS>
DS> DS>---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
D

Dave Sexton

Hi Michael,

Well, I'm indifferent to the name and how Microsoft markets their products.
It provides functionality that will be useful to me and I suspect that it
will be useful to Michael C as well.

- Dave Sexton
 
G

Greg Young

It is important to remember that this is not actually putting the methods
onto the original instance but are simply sugar ..

What actually ends up happenning is the equivalent of

static MyMethod(MyObject _Target)

the compiler will then generate calls passing the original instance to your
static method. If you were to actually inspect the object you have not
actually added a method to it.

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
 
D

Dave Sexton

Hi Greg,

Understood. I'm simply suggesting a means for handling Michael C's problem
in the future without requiring refactoring of all uses of the Bitmap class
to another class.

I played around with the LINQ preview and found this particular feature to
be, potentially, very useful.

- Dave Sexton
 
C

Chris Nahr

Hi Michael,

In .NET 3.0 (shipping with Windows Vista, so I've heard) there are Extender
methods so you can decorate instances of any object or interface with your
own methods and their implementations.

Nope, that's .NET 3.5 -- or whatever the final name will be.

The .NET 3.0 release that ships with Vista will not contain LINQ etc.,
just the various library packages: WPF, WCF, CS, etc. .NET 3.5 will
be released at a later time.
 
J

Jon Skeet [C# MVP]

Dave Sexton said:
In .NET 3.0 (shipping with Windows Vista, so I've heard) there are Extender
methods so you can decorate instances of any object or interface with your
own methods and their implementations.

You can add methods, but you can't add any data - so Michael couldn't
really do what he wants, which is to add a Tag property (unless that
could be derived from the existing data).
 
M

Michael C

Dave Sexton said:
Hi Michael,

Well, I'm indifferent to the name and how Microsoft markets their
products. It provides functionality that will be useful to me and I
suspect that it will be useful to Michael C as well.

Sounds like that would be useful. I'm still on 1.1 so maybe can jump 2
versions at once :)

Michael
 
D

Dave Sexton

Hi Michael,

Yea, I figured you were on 1.1 because the 2.0 Framework has a Tag property
on the Image class, which Bitmap inherits.

For a code snippet that performs exactly what your asking for with the 3.0
C# compiler and extension methods see my response to Jon Skeet's post in
this thread.

- Dave Sexton
 
D

Dave Sexton

Hi Jon,

Actually your statement is incorrect. The following code works fine in the
LINQ Preview, C# 3.0 compiler of May 2006. Also, the docs for the C# 3.0
compiler state that extension properties, events and operators are being
considered. Do you know if they've come to a decision whether to include
those features?

The following code allows any instance of an object, of any Type, to have an
associated object at runtime using SetTag and GetTag methods. I've also
included a non-generic implementation that explicitly extends the Bitmap
class only:

Extensions.cs

using System;
using System.Collections.Generic;
using System.Drawing;

namespace LINQHandsOnLab.Extensions
{
public static class BitmapExtensions
{
private static Dictionary<Bitmap, object> bitmapTags;

public static void SetTag(this Bitmap bitmap, object value)
{
if (bitmapTags == null)
bitmapTags = new Dictionary<Bitmap, object>();

bitmapTags[bitmap] = value;
}

public static object GetTag(this Bitmap bitmap)
{
if (bitmapTags == null)
bitmapTags = new Dictionary<Bitmap, object>();

if (bitmapTags.ContainsKey(bitmap))
return bitmapTags[bitmap];
else
return null;
}
}

/// <summary>Provides <see cref="GetTag" /> and
/// <see cref="SetTag" /> extension methods to all object instances.
/// </summary>
public static class ObjectTagExtensions
{
private static Dictionary<object, object> objectTags;

public static void SetTag<T>(this T obj, object value)
{
if (objectTags == null)
objectTags = new Dictionary<object, object>();

objectTags[obj] = value;
}

public static object GetTag<T>(this T obj)
{
if (objectTags == null)
objectTags = new Dictionary<object, object>();

if (objectTags.ContainsKey(obj))
return objectTags[obj];
else
return null;
}
}
}

Test the above with the following Console application:
Program.cs

using System;
using System.Collections.Generic;
using System.Text;

// this using declaration is required so the compiler will resolve the
extension methods
using LINQHandsOnLab.Extensions;

using System.Drawing;
using System.Data;

class Program
{
static void Main()
{
Bitmap bitmap1 = new Bitmap(100, 100);

bitmap1.SetTag(10);

// write 10...
Console.WriteLine("bitmap1 Tag: {0}", bitmap1.GetTag());

Bitmap bitmap2 = new Bitmap(150, 50);

// write a blank line (null reference)...
Console.WriteLine("bitmap2 Tag: {0}", bitmap2.GetTag());

// Create a DataSet and 'tag' the instance with an arbitrary object
DataSet data = new DataSet();

data.SetTag("Custom String Info");

// write "Custom String Info"...
Console.WriteLine("data Tag: {0}", data.GetTag());

Console.ReadLine();
}
}

Output:

bitmap1 Tag: 10
bitmap2 Tag:
data Tag: Custom String Info

- Dave Sexton
 
J

Jon Skeet [C# MVP]

Dave Sexton said:
Actually your statement is incorrect.

I don't think so.
The following code works fine in the
LINQ Preview, C# 3.0 compiler of May 2006. Also, the docs for the C# 3.0
compiler state that extension properties, events and operators are being
considered. Do you know if they've come to a decision whether to include
those features?

The following code allows any instance of an object, of any Type, to have an
associated object at runtime using SetTag and GetTag methods.

Yes - and it leaks memory unless you explicitly remove the tag from the
dictionary. The problem is that you're able to add methods and
properties etc, but not *data*. That's why I included the bit in
brackets: "unless that could be derived from the existing data". You're
effectively doing that by using separately stored data, with the
existing data being the reference itself used to look up the tag in the
dictionary.

This is really *not* the same as being able to derive from Bitmap - the
constraints on the caller are much, much bigger.
 
J

Jeff Louie

Hi Michael... Some authors have argued that unless a class is
specifically
designed and documented to be safely subclassed it should be sealed
(Joshua
Bloch Effective Java). In the same vein, it has been argued to favor
composition
and forwarding over inheritance (Synder 1986) since inheritance breaks
encapsulation.

A concrete example is a type safe collection. A naive programmer could
extend
from the type safe collection and add non type safe setters.

Regards,
Jeff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top