Override property

S

shapper

Hello,

I have a class A with the property Title:

public class A {
public String Title { get; set; }
}

And a class B then inherits A and has the following properties:

public class B {
public String Name { get; set; }
public String TitleSeparator { get; set; }

public override String Title { get { return String.Concat(title,
TitleSeparator, Name); } set { title = value; } }
private String title;
}

I need to override Title property in A so it gets the value Title +
TitleSeparator + Name.

I am getting an error:
B.Title.get': cannot override inherited member 'A.Title.get' because
it is not marked virtual, abstract, or override

I am marking it as override. You can see on my code.

What am I missing?

Thanks,
Miguel
 
S

shapper

You can't do that.  Even if you could, it's very bad practice to have a 
setter take as input something different than what you'd get as output  
 from the getter.

Now I am confused.

Basically what I am trying to do is something as follows:

When I define the Title property,

B myB = new B();
B.Title = "My Title";

I would like B.Title value to become B.Title + B.TitleSeparator +
B.Name

Is this not possible or the way I am doing is wrong?

I am doing this because my B class is something as follows:

public class B : A {
public String Name { get; set; }
public String TitleSeparator { get; set; }
public String Title { get; set; }

public B() {
Name = "Sample Name";
TitleSeparator = "-";
Title = String.Empty;
}
}

So I set default values for the first two properties.

Later in my code I do something like:

ContainerClass = new ContainerClass {
B = new B { Title = "This Page Title" }
}

And I would like Title to become Title + TitleSeparator + Name with no
more need of code;

Well this is how I am thinking ... probably wrong.

(Note: my B class is public class B : A { ... I forgot the ":A" part
on my previous post)

Thanks,
Miguel
 
S

shapper

You can't do that.  Even if you could, it's very bad practice to have a 
setter take as input something different than what you'd get as output  
 from the getter.

Now I am confused.

Basically what I am trying to do is something as follows:

When I define the Title property,

B myB = new B();
B.Title = "My Title";

I would like B.Title value to become B.Title + B.TitleSeparator +
B.Name

Is this not possible or the way I am doing is wrong?

I am doing this because my B class is something as follows:

public class B : A {
public String Name { get; set; }
public String TitleSeparator { get; set; }
public String Title { get; set; }

public B() {
Name = "Sample Name";
TitleSeparator = "-";
Title = String.Empty;
}
}

So I set default values for the first two properties.

Later in my code I do something like:

ContainerClass = new ContainerClass {
B = new B { Title = "This Page Title" }
}

And I would like Title to become Title + TitleSeparator + Name with no
more need of code;

Well this is how I am thinking ... probably wrong.

(Note: my B class is public class B : A { ... I forgot the ":A" part
on my previous post)

Thanks,
Miguel
 
J

Jesse Houwing

Hello shapper,
Now I am confused.

Basically what I am trying to do is something as follows:

When I define the Title property,

B myB = new B();
B.Title = "My Title";
I would like B.Title value to become B.Title + B.TitleSeparator +
B.Name

Is this not possible or the way I am doing is wrong?

I am doing this because my B class is something as follows:

public class B : A {
public String Name { get; set; }
public String TitleSeparator { get; set; }
public String Title { get; set; }
public B() {
Name = "Sample Name";
TitleSeparator = "-";
Title = String.Empty;
}
}
So I set default values for the first two properties.

Later in my code I do something like:

ContainerClass = new ContainerClass {
B = new B { Title = "This Page Title" }
}
And I would like Title to become Title + TitleSeparator + Name with no
more need of code;

Well this is how I am thinking ... probably wrong.

(Note: my B class is public class B : A { ... I forgot the ":A" part
on my previous post)


I think the best way to approach this is to override ToString and let that
create the title for you.

To do it the way you're doing it, you'll have to make the Title property
in type A virtual, so that you can override it in type B like so:

class A{

public virtual string Title
{
get;
set;
}

}

class B{

public override string Title
{
get
{
return base.Title + TitleSeparator + Name
}
set;
}

A better way would be to look at the name and try and find a better solution.
As Title in itself seems to be a little more than just a string... It could
be multiple strings, depending on where in the hyrarchy you are...

To me the original Title would be more like MainTitle, while the second (in
type B) would be a SubTitle...

Then you could have a Title Property (get only) which returns the right title
in every type:

class A
{

public virtual string Title
{
get { return MainTitle; }
}

public string MainTitle {get; set;}

public override string ToString()
{
return Title;
}
}

class B
{
public override string Title
{
get { return base.MainTitle + TitleSeparator + SubTitle; }
}

public string SubTitle {get; set;}
}
 
J

Jesse Houwing

Hello shapper,
Now I am confused.

Basically what I am trying to do is something as follows:

When I define the Title property,

B myB = new B();
B.Title = "My Title";
I would like B.Title value to become B.Title + B.TitleSeparator +
B.Name

Is this not possible or the way I am doing is wrong?

I am doing this because my B class is something as follows:

public class B : A {
public String Name { get; set; }
public String TitleSeparator { get; set; }
public String Title { get; set; }
public B() {
Name = "Sample Name";
TitleSeparator = "-";
Title = String.Empty;
}
}
So I set default values for the first two properties.

Later in my code I do something like:

ContainerClass = new ContainerClass {
B = new B { Title = "This Page Title" }
}
And I would like Title to become Title + TitleSeparator + Name with no
more need of code;

Well this is how I am thinking ... probably wrong.

(Note: my B class is public class B : A { ... I forgot the ":A" part
on my previous post)


I think the best way to approach this is to override ToString and let that
create the title for you.

To do it the way you're doing it, you'll have to make the Title property
in type A virtual, so that you can override it in type B like so:

class A{

public virtual string Title
{
get;
set;
}

}

class B{

public override string Title
{
get
{
return base.Title + TitleSeparator + Name
}
set;
}

A better way would be to look at the name and try and find a better solution.
As Title in itself seems to be a little more than just a string... It could
be multiple strings, depending on where in the hyrarchy you are...

To me the original Title would be more like MainTitle, while the second (in
type B) would be a SubTitle...

Then you could have a Title Property (get only) which returns the right title
in every type:

class A
{

public virtual string Title
{
get { return MainTitle; }
}

public string MainTitle {get; set;}

public override string ToString()
{
return Title;
}
}

class B
{
public override string Title
{
get { return base.MainTitle + TitleSeparator + SubTitle; }
}

public string SubTitle {get; set;}
}
 
S

shapper

I think the best way to approach this is to override ToString and let that
create the title for you.

What do you mean? Creating a custom type converter?

To do it the way you're doing it, you'll have to make the Title property
in type A virtual, so that you can override it in type B like so:

class A{

public virtual string Title
{
get;
set;

}
}

class B{

public override string Title
{
get
{
return base.Title + TitleSeparator + Name

}
set;
}

I did but I get the following error on set:
'Title.set' must declare a body because it is not marked abstract,
extern, or partial

I am not sure but since the get is not on the short form I need change
the set to:
public override string Title { get { return String.Concat
(base.Title, " - ", Name); } set { title = value; } }
private String title;
A better way would be to look at the name and try and find a better solution.
As Title in itself seems to be a little more than just a string... It could
be multiple strings, depending on where in the hyrarchy you are...

Basically Title is the page title.
On each ASP.NET MVC Controller Action (Renders a page) I define the
title.

But then on B class I want to add " - Site Name" to the title.
I placed "-" in TitleSeparator property and "Site Name" in Name
property.

This way for a particular page, if I need to change it I can.

The reason why this is getting complex is that A is a class inside a
library that I use in all sites and it contains properties like Title,
Keywords, Scripts, etc ...

TitleSeparator and Name is specific to each project implementation so
it is in class B that inherits class A to bring all those common
properties.
 
S

shapper

I think the best way to approach this is to override ToString and let that
create the title for you.

What do you mean? Creating a custom type converter?

To do it the way you're doing it, you'll have to make the Title property
in type A virtual, so that you can override it in type B like so:

class A{

public virtual string Title
{
get;
set;

}
}

class B{

public override string Title
{
get
{
return base.Title + TitleSeparator + Name

}
set;
}

I did but I get the following error on set:
'Title.set' must declare a body because it is not marked abstract,
extern, or partial

I am not sure but since the get is not on the short form I need change
the set to:
public override string Title { get { return String.Concat
(base.Title, " - ", Name); } set { title = value; } }
private String title;
A better way would be to look at the name and try and find a better solution.
As Title in itself seems to be a little more than just a string... It could
be multiple strings, depending on where in the hyrarchy you are...

Basically Title is the page title.
On each ASP.NET MVC Controller Action (Renders a page) I define the
title.

But then on B class I want to add " - Site Name" to the title.
I placed "-" in TitleSeparator property and "Site Name" in Name
property.

This way for a particular page, if I need to change it I can.

The reason why this is getting complex is that A is a class inside a
library that I use in all sites and it contains properties like Title,
Keywords, Scripts, etc ...

TitleSeparator and Name is specific to each project implementation so
it is in class B that inherits class A to bring all those common
properties.
 
S

shapper

Now, you haven't given enough information to know what that last thing is 
called.  Maybe it's a "Document Name" or perhaps it's a "File Name" or  
maybe it's a "Remote Host Name".  Let's just call it "OtherName" for now.

I just wrote a better explanation.

My classes are just like that.
They have a few more properties and nothing else.

I just named them A and B because I didn't copied the code.

But A is PageHead and B is PageEngine.

PageHead (A) > Contains properties like Title, Keywords, Scripts and
Styles and I use it in all my projects.

PageEngine (B)> Specific to this project where I need to add the title
separator and site name " - Site Name"

I don't want to mess a lot in class A only to satisfy the needs of a
specific project.
 
S

shapper

Now, you haven't given enough information to know what that last thing is 
called.  Maybe it's a "Document Name" or perhaps it's a "File Name" or  
maybe it's a "Remote Host Name".  Let's just call it "OtherName" for now.

I just wrote a better explanation.

My classes are just like that.
They have a few more properties and nothing else.

I just named them A and B because I didn't copied the code.

But A is PageHead and B is PageEngine.

PageHead (A) > Contains properties like Title, Keywords, Scripts and
Styles and I use it in all my projects.

PageEngine (B)> Specific to this project where I need to add the title
separator and site name " - Site Name"

I don't want to mess a lot in class A only to satisfy the needs of a
specific project.
 
S

shapper

Maybe this is a "lost in translation" thing, but I don't understand why an  
"engine" inherits a "head".  It seems to me that the only thing that would  
inherit a "head" class would be other classes that are more specialized  
types of "head".

You are right. In fact both classes are at same level.
Let's call both classes Page.
So Page in my common library contains properties that I use in all my
projects.
The other inside my project extends the original one by adding a few
more properties specific to the project.
Then I pass this class in my ViewModel so the View (Html) can use all
properties where necessary.

So I took another approach: partial classes. So on my Common library I
have:

namespace Common {
public partial class Page {
public String Keywords { get; set; }
public String Description { get; set; }
public String Title { get; set; }
}
}

And on my project I have:

namespace MvcProject {
public partial class Page {
public String TitleSeparator { get; set; }
public String Name { get; set; }
public String Language { get; set; }
}
}

Now on my ViewModel I would need to define a property of type Page to
pass to the view:

public class ViewModel {
public Page Page { get; set; }
public ViewModel() {
Page = new Page {
Description = "This web site",
Keywords = "First,Second,Third",
Title = "Web Page Title",
TitleSeparator = " - ",
Name = " My MVC Web Site"
};
} // ViewModel

This does now work because I get the error:
'MvcProject.Page' does not contain a definition for 'Title'

This is because the ViewModel interprets the Page class as one or the
other.
So I got stuck again ... :)

Was this such a bad idea?

I am just trying to make this right because I will use it in all my
projects.

Thanks,
Miguel
 
S

shapper

Maybe this is a "lost in translation" thing, but I don't understand why an  
"engine" inherits a "head".  It seems to me that the only thing that would  
inherit a "head" class would be other classes that are more specialized  
types of "head".

You are right. In fact both classes are at same level.
Let's call both classes Page.
So Page in my common library contains properties that I use in all my
projects.
The other inside my project extends the original one by adding a few
more properties specific to the project.
Then I pass this class in my ViewModel so the View (Html) can use all
properties where necessary.

So I took another approach: partial classes. So on my Common library I
have:

namespace Common {
public partial class Page {
public String Keywords { get; set; }
public String Description { get; set; }
public String Title { get; set; }
}
}

And on my project I have:

namespace MvcProject {
public partial class Page {
public String TitleSeparator { get; set; }
public String Name { get; set; }
public String Language { get; set; }
}
}

Now on my ViewModel I would need to define a property of type Page to
pass to the view:

public class ViewModel {
public Page Page { get; set; }
public ViewModel() {
Page = new Page {
Description = "This web site",
Keywords = "First,Second,Third",
Title = "Web Page Title",
TitleSeparator = " - ",
Name = " My MVC Web Site"
};
} // ViewModel

This does now work because I get the error:
'MvcProject.Page' does not contain a definition for 'Title'

This is because the ViewModel interprets the Page class as one or the
other.
So I got stuck again ... :)

Was this such a bad idea?

I am just trying to make this right because I will use it in all my
projects.

Thanks,
Miguel
 
A

Alexander Mueller

shapper said:
public class A {
public String Title { get; set; }
}

And a class B then inherits A and has the following properties:

public class B {
public String Name { get; set; }
public String TitleSeparator { get; set; }

public override String Title { get { return String.Concat(title,
TitleSeparator, Name); } set { title = value; } }
private String title;
}

I need to override Title property in A so it gets the value Title +
TitleSeparator + Name.

I am getting an error:
B.Title.get': cannot override inherited member 'A.Title.get' because
it is not marked virtual, abstract, or override

I am marking it as override. You can see on my code.

What am I missing?

You need to add 'virtual' or 'abstract', but not 'override'
to the Title-property of your base-class 'A'.

abstract fits best, since yor A-class has no implementation for Title;
abstract means incomplete or no implementation, it's up to the dervied
class to fully implemented the base class signatures.
Note that also the class itself must be marked abstract if it contains a
abstract member;
abstract classes can't be created themselfes, only derived classes that
implement all abstract members can be created.

virtual what be your favorite choice if you'd had implementaion for
Title in A, which you want to override or extend in B.
classes with virtual members can be created themselves.


MfG,
Alex


class Program
{
static void Main(string[] args)
{
var b = new B { Title = "B-virtual" };
var bb = new BB { Title = "BB-abstract" };
Console.WriteLine("{0} {1}", b.Title, bb.Title);
Console.ReadLine();
}
}

//virtual solution
public class A
{
protected string _title = null;
public virtual string Title
{
get{return _title;}
set{_title = value ;}
}
}
public class B : A
{

private const string TitleSeparator = "-";
private const string Name = "Name";

public override string Title
{
get { return string.Concat(base.Title,
TitleSeparator, Name); }
set { base.Title = value; }
}
}

//abstract solution
public abstract class AA
{
public abstract string Title { get; set; }
}
public class BB : AA
{
private string _title = null;

private const string TitleSeparator = "-";
private const string Name = "Name";

public override string Title
{
get { return string.Concat(_title,
TitleSeparator, Name); }
set { _title = value; }
}
}
 
A

Alexander Mueller

shapper said:
public class A {
public String Title { get; set; }
}

And a class B then inherits A and has the following properties:

public class B {
public String Name { get; set; }
public String TitleSeparator { get; set; }

public override String Title { get { return String.Concat(title,
TitleSeparator, Name); } set { title = value; } }
private String title;
}

I need to override Title property in A so it gets the value Title +
TitleSeparator + Name.

I am getting an error:
B.Title.get': cannot override inherited member 'A.Title.get' because
it is not marked virtual, abstract, or override

I am marking it as override. You can see on my code.

What am I missing?

You need to add 'virtual' or 'abstract', but not 'override'
to the Title-property of your base-class 'A'.

abstract fits best, since yor A-class has no implementation for Title;
abstract means incomplete or no implementation, it's up to the dervied
class to fully implemented the base class signatures.
Note that also the class itself must be marked abstract if it contains a
abstract member;
abstract classes can't be created themselfes, only derived classes that
implement all abstract members can be created.

virtual what be your favorite choice if you'd had implementaion for
Title in A, which you want to override or extend in B.
classes with virtual members can be created themselves.


MfG,
Alex


class Program
{
static void Main(string[] args)
{
var b = new B { Title = "B-virtual" };
var bb = new BB { Title = "BB-abstract" };
Console.WriteLine("{0} {1}", b.Title, bb.Title);
Console.ReadLine();
}
}

//virtual solution
public class A
{
protected string _title = null;
public virtual string Title
{
get{return _title;}
set{_title = value ;}
}
}
public class B : A
{

private const string TitleSeparator = "-";
private const string Name = "Name";

public override string Title
{
get { return string.Concat(base.Title,
TitleSeparator, Name); }
set { base.Title = value; }
}
}

//abstract solution
public abstract class AA
{
public abstract string Title { get; set; }
}
public class BB : AA
{
private string _title = null;

private const string TitleSeparator = "-";
private const string Name = "Name";

public override string Title
{
get { return string.Concat(_title,
TitleSeparator, Name); }
set { _title = value; }
}
}
 
A

Alexander Mueller

Peter said:
[...]
abstract fits best, since yor A-class has no implementation for Title;

"abstract" might be appropriate, but it's not true that class "A" has no
implementation for Title.

Sorry i wasn't familiar with that

public String Title { get; set; }

-Thing. I thought it'd do the same thing as in an interface, i.e.
declare but not implement the property, i was missing the assignment in
the setter and the return in the getter.
Now I realize that it also creates a hidden data member for us behind
the scenes. Very nice.
It does, and Miguel may actually prefer to preserve that implementation so that sub-classes don't need to provide
it if they don't want to override the property.

Yes the getter in the derived class B is kind of odd.
An extra Readonly prop would be the cleaner way at first glance.
But on the other hand there is no need for not having any
special code in a prop, if you only want to assign and return a
value a field is all you need.
Also if the classes serves as data-source and the B-items shall
return more extended info in the Title-column as the the A-items do,
then this is solution where you don't have to change anything in the
data binding and the code that set the binding doesn't have to
distinguish between derived and basic types.
So at least it works without excessivly changing the OO-model.

MfG,
Alex
 
A

Alexander Mueller

Peter said:
[...]
abstract fits best, since yor A-class has no implementation for Title;

"abstract" might be appropriate, but it's not true that class "A" has no
implementation for Title.

Sorry i wasn't familiar with that

public String Title { get; set; }

-Thing. I thought it'd do the same thing as in an interface, i.e.
declare but not implement the property, i was missing the assignment in
the setter and the return in the getter.
Now I realize that it also creates a hidden data member for us behind
the scenes. Very nice.
It does, and Miguel may actually prefer to preserve that implementation so that sub-classes don't need to provide
it if they don't want to override the property.

Yes the getter in the derived class B is kind of odd.
An extra Readonly prop would be the cleaner way at first glance.
But on the other hand there is no need for not having any
special code in a prop, if you only want to assign and return a
value a field is all you need.
Also if the classes serves as data-source and the B-items shall
return more extended info in the Title-column as the the A-items do,
then this is solution where you don't have to change anything in the
data binding and the code that set the binding doesn't have to
distinguish between derived and basic types.
So at least it works without excessivly changing the OO-model.

MfG,
Alex
 
S

shapper

Peter said:
On Sat, 09 May 2009 21:09:26 -0700, Alexander Mueller
[...]
abstract fits best, since yor A-class has no implementation for Title;
"abstract" might be appropriate, but it's not true that class "A" has no
implementation for Title.

Sorry i wasn't familiar with that

        public String Title { get; set; }

-Thing. I thought it'd do the same thing as in an interface, i.e.
declare but not implement the property, i was missing the assignment in
the setter and the return in the getter.
Now I realize that it also creates a hidden data member for us behind
the scenes. Very nice.
It does, and Miguel may actually prefer to preserve that implementationso that sub-classes don't need to provide
it if they don't want to override the property.

Yes the getter in the derived class B is kind of odd.
An extra Readonly prop would be the cleaner way at first glance.
But on the other hand there is no need for not having any
special code in a prop, if you only want to assign and return a
value a field is all you need.
Also if the classes serves as data-source and the B-items shall
return more extended info in the Title-column as the the A-items do,
then this is solution where you don't have to change anything in the
data binding and the code that set the binding doesn't have to
distinguish between derived and basic types.
So at least it works without excessivly changing the OO-model.

MfG,
Alex

I am testing all solutions to check which one better fits my MVC
project ...
 
S

shapper

Peter said:
On Sat, 09 May 2009 21:09:26 -0700, Alexander Mueller
[...]
abstract fits best, since yor A-class has no implementation for Title;
"abstract" might be appropriate, but it's not true that class "A" has no
implementation for Title.

Sorry i wasn't familiar with that

        public String Title { get; set; }

-Thing. I thought it'd do the same thing as in an interface, i.e.
declare but not implement the property, i was missing the assignment in
the setter and the return in the getter.
Now I realize that it also creates a hidden data member for us behind
the scenes. Very nice.
It does, and Miguel may actually prefer to preserve that implementationso that sub-classes don't need to provide
it if they don't want to override the property.

Yes the getter in the derived class B is kind of odd.
An extra Readonly prop would be the cleaner way at first glance.
But on the other hand there is no need for not having any
special code in a prop, if you only want to assign and return a
value a field is all you need.
Also if the classes serves as data-source and the B-items shall
return more extended info in the Title-column as the the A-items do,
then this is solution where you don't have to change anything in the
data binding and the code that set the binding doesn't have to
distinguish between derived and basic types.
So at least it works without excessivly changing the OO-model.

MfG,
Alex

I am testing all solutions to check which one better fits my MVC
project ...
 
J

Jeff Johnson

I am getting an error:
B.Title.get': cannot override inherited member 'A.Title.get' because
it is not marked virtual, abstract, or override

I am marking it as override. You can see on my code.

Overriding is a two-way street. Not only do you have to specify that you're
overriding it in the derived class, but you have to specify that it CAN be
overridden in the BASE class. So in the base you have to use the "virtual"
keyword and in the derived you have to use "override." This is one of those
cases where I like VB's implementation better. Its keyword for the base
class is "Overridable," which is far more clear than C#'s use of the legacy
C++ "virtual" keyword.
 
J

Jeff Johnson

I am getting an error:
B.Title.get': cannot override inherited member 'A.Title.get' because
it is not marked virtual, abstract, or override

I am marking it as override. You can see on my code.

Overriding is a two-way street. Not only do you have to specify that you're
overriding it in the derived class, but you have to specify that it CAN be
overridden in the BASE class. So in the base you have to use the "virtual"
keyword and in the derived you have to use "override." This is one of those
cases where I like VB's implementation better. Its keyword for the base
class is "Overridable," which is far more clear than C#'s use of the legacy
C++ "virtual" keyword.
 

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