[C#] Override a property.. ARGH!

Caporegime
Joined
18 Oct 2002
Posts
29,493
Location
Back in East London
I'm overriding a property. Well, trying to.

Code:
namespace Foo {
  public class A {
    public TypeA property = new TypeA();
  }

  public void SetSomething(string foo)
  {
    property.blah = foo;
  }
}

namespace Bar {
  public class B : Foo.A {
    public TypeB property = new TypeB();
  }
}

Bar.B foo = new Bar.B();
foo.SetSomething("woowoo");
if (foo.property.blah == null)
{
  // yes, it's null. :(
}

What the deuce?
 
Last edited:
Try this for a starter, although there is a better example here: http://www.java2s.com/Code/CSharp/Class-Interface/OverrideProperties.htm. You are really going to need to go through some tutorials to understand the fundamentals.

Code:
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass test = new BaseClass();
            // Should equal "baseClassString"
            string a = test.BaseClassString;

            DerivedClass test2 = new DerivedClass();
            //Should equal "derivedClassString"
            string b = test2.BaseClassString;

        }
    }

Code:
namespace TestNamespace
{
    public class BaseClass
    {
        private string baseClassString = "baseClassString";

        public virtual string BaseClassString
        {
            get
            {
                return this.baseClassString;
            }
            set
            {
                this.baseClassString = value;
            }
        }
    }

    public class DerivedClass : BaseClass
    {
        public override string  BaseClassString
        {
	        get 
	        { 
		   return "derivedClassString";
	        }
	          set 
	        { 
		   base.BaseClassString = value;
	        }
        }
    }
}
 
I've been reading through those already, but given what I have builds and runs (but just not with the desired behaviour) I don't see your point of there being a syntax error?

Basically, I'm wanting to override the type of the property. Along with the B extending A, the properties are also subclasses of each other (i.e. TypeB extends TypeA to add extra properties.)

Simply put, declaring an override property on a subclass does not override, it adds another property with the same name - just not on base. The methods/accessors/mutators whatever on base will not use the property of the subclass. Stupid. Why would you *ever* want to do that?
 
Last edited:
You appear to be using public fields here not properties, but anyway you can't change the return type of a property in C#.

If you want the same property name, but different return type in a derived class you would have to shadow it using the new keyword, but then you lose the polymorphism that you want.
Have a look here for some more detail:
http://msdn.microsoft.com/en-us/library/ms172785.aspx

There is a question here on the same lines, might provide some insight into possible ways around this?
http://stackoverflow.com/questions/157119/c-can-i-override-with-derived-types
 
Public fields is indeed what I mean. :)

I'm looking those links now, thanks... but I do find it amazing that something so simple has to be so difficult. :) -1 to type strict languages again :p
 
Nah, all I want to do is override the type assigned to a field. If it were not type-strict, it would be sans problem. :)
 
(Ignoring that you've used fields rather than properties)

It would break .NET's type safety if you were allowed to covariantly override properties' types, and moreover it would be semantically inconsistent (it violates the Liskov substitution principle).

For example, say you have a TypeC that derives from TypeA. If you instantiate class B, then class A's interface should allow you to assign an instance of TypeC to the property. However, class B's interface does not allow this; hence you would encounter runtime errors.

Technically it would be valid if the property were read-only, but this only occurs in particular cases (properties with no set accessor), and the CLR has limitations that prevent it I believe (including covariance of method return types). Eric Lippert did a very good series of articles on covariance and contravariance in .NET which is worth reading:
http://blogs.msdn.com/ericlippert/a...ariance-and-contravariance-in-c-part-one.aspx

To me this is indicative of bad design, since the parent class's interface specifies that the property may be assigned a value that actually you don't want it to be assigned. Even in a dynamically typed language you would get unexpected results if you were to do this, even though it wouldn't generate an error.
 
Last edited:
No, the problem is specifically because there are two objects/classes that are identical for all but two fields, hence the extension in the first place, but they do not implement this arbitrary thing called an Interface, despite their actual interface (as in, they have the same methods and properties - just different fields) being identical. Infact the two classes are even called exactly the same thing, just different namespaces.

In C# this "limitation" means that the base class methods, when accessed via a derived object, will update/interact with the derived object properties - at least, it should. It doesn't. The object maintains two instances of the field; one on base, one on the derived class that at first glance appears to be a wrapper on the base class, instead of an extended instance like it should be - and I might add, every other language manages.

I've read Buu Nguyen's blog on this very subject, and it leaves me thinking "So, you've disallowed covariance/contravariance simply because you don't want developers to cause an error in their code.. who the hell are you you patronise so blatantly?" :)

I'm going to bleat about Smalltalk again, because quite frankly it rocks (:p) and has been doing what .NET (and Java) have been unable to do for 50 years; it sensibly handles these kinds of problems by allowing you, the developer, to shoot yourself in the foot every now and then, and to actually learn from it. :) This error/problem with .NET does nothing of the sort, it just leaves me confused, and asking "What they hell were they thinking?" :)
 
Last edited:
No, the problem is specifically because there are two objects/classes that are identical for all but two fields, hence the extension in the first place, but they do not implement this arbitrary thing called an Interface, despite their actual interface (as in, they have the same methods and properties - just different fields) being identical. Infact the two classes are even called exactly the same thing, just different namespaces.

I don't follow. You've said that their interfaces are identical, but that their fields are different? If the field isn't private (which it should be, by standard OOP practice), then it is part of the class's interface.

The example I gave pretty clearly illustrates the semantic problems with what you're trying to do, doesn't it? You've specified in the superclass A that whatever's contained in that property should satisfy certain predicates. The subclass B then adds to those predicates; however, A's interface requires that you be able to set the value to an object satisfying only the smaller set of predicates. If this is the case, then B's requirement that the property value satisfy the larger set of predicates is not met. Hence, covariance in this case is inconsistent.

In C# this "limitation" means that the base class methods, when accessed via a derived object, will update/interact with the derived object properties - at least, it should. It doesn't. The object maintains two instances of the field; one on base, one on the derived class that at first glance appears to be a wrapper on the base class, instead of an extended instance like it should be - and I might add, every other language manages.

Yeah, polymorphism isn't supported on fields; the only thing that could be overridden is the type, and that wouldn't make sense (as demonstrated above). Polymorphism is supported on properties, however, as their implementation can be overridden (though type variance isn't supported for the same reason), so just use them.

I think what you're describing there is member replacement, which is where rather than being overridden, the base member is 'hidden' by the new member. This is what happens when you don't use the virtual/override keywords, and is generally considered bad practice in C#, as it breaks polymorphism.

C# doesn't allow for covariance/contravariance in the specific cases of read-only/write-only properties because it would give rise to inconsistent behaviour ("I can override the type of a property with only a getter but not one with a setter as well!?"). I don't like this decision very much but there ain't nothing I can do about it :)

I've read Buu Nguyen's blog on this very subject, and it leaves me thinking "So, you've disallowed covariance/contravariance simply because you don't want developers to cause an error in their code.. who the hell are you you patronise so blatantly?" :)

They've disallowed it because it's necessary in order for C#'s static typing system to be self-consistent. If you don't like static typing, then fair enough, but don't knock C# for not giving a broken implementation of it!

I'm going to bleat about Smalltalk again, because quite frankly it rocks (:p) and has been doing what .NET (and Java) have been unable to do for 50 years; it sensibly handles these kinds of problems by allowing you, the developer, to shoot yourself in the foot every now and then, and to actually learn from it. :) This error/problem with .NET does nothing of the sort, it just leaves me confused, and asking "What they hell were they thinking?" :)

You seem to have a lot of hate for statically typed languages, but I use both statically and dynamically typed languages and I've honestly never encountered any problems with them. I find that static typing is useful (linguistic limitations aside) because it enforces semantic consistency as well as preventing potential runtime errors.
 
Last edited:
The interface is extended. ClassA's interface is in tact, and ClassB extends it; the member type that I wish to override (which I'll dub InterfaceA) in ClassA is with a type that is an extension of InterfaceA (ingeniously dubbed InterfaceB)

The interface, according to the base methods and properties, is un changed. The derived class will use the extended member methods and properties, whilst the base members will be unchanged. Simply because the objects I am using do not have "InterfaceB : InterfaceA" it is not allowed. This is a hinderance, and only one that is achieved via a type-strict language :)

I do have a certian dislike for type-strict languages. The perfect example being this very problem, which is not even a concern in dynamic typed languages. It just simply does not happen with issue, it just works. If an object responds to a method, it should answer it. Not fail to compile because I did not apply an arbitray piece of code telling everything that it should. :)
 
Ultimately it comes down to this. Type strict language developers (ala Buu Nguyen, one of the authors of C# for those that do not know) have imposed these restrictions "to protect developers" ... from their own mistakes, or to be more exact, from the failings of the language in question. So you, as a developer, must adhere to their frame of mind when developing. I strongly disagree with anyone who thinks this is anything but patronisation. :)
 
Then continue developing in Smalltalk or produce your own language?

It comes down to the simple concept of... "using the correct tool for the job".
 
The interface is extended. ClassA's interface is in tact, and ClassB extends it; the member type that I wish to override (which I'll dub InterfaceA) in ClassA is with a type that is an extension of InterfaceA (ingeniously dubbed InterfaceB)

The interface, according to the base methods and properties, is un changed. The derived class will use the extended member methods and properties, whilst the base members will be unchanged. Simply because the objects I am using do not have "InterfaceB : InterfaceA" it is not allowed. This is a hinderance, and only one that is achieved via a type-strict language :)

I'm not quite sure what you're trying to say here, but I think you're misunderstanding the nature of polymorphism in .NET. Fields are intentionally not polymorphic in a statically typed language because it doesn't make sense for them to be unless they're either read-only or write-only.

The field on the derived class is hiding the field in the base class because in a statically typed language it is not possible to override it. This is not a limitation of static typing, but a semantic problem with what you're trying to do.

I'm not even sure what you'd be trying to achieve by overriding the field in a dynamically typed language anyway; there is no type specification on the field, so what is there to override? :confused:

Still, though, I'm not sure why you can't see the semantic problems with your goal. As I've said, static typing not only mandates type consistency, but it also introduces the notion of semantic consistency, which isn't present with dynamic typing. In specifying the type of a member, you're also – to some extent – specifying what it is and what it should do, which is why consistency is so important.

I do have a certian dislike for type-strict languages. The perfect example being this very problem, which is not even a concern in dynamic typed languages.

Again, I can't say I've ever come across typing problems like this in C#. Maybe your dynamic typing just makes you more lax in your approach to OOP :p

It just simply does not happen with issue, it just works. If an object responds to a method, it should answer it. Not fail to compile because I did not apply an arbitray piece of code telling everything that it should. :)

Well that's just how nominal subtyping and statically typed languages work, sorry :/

Returning to the original problem, though, if the field is read-only, then you can make it a property with only a get accessor and then hide the base property with the the derived class's property using the new keyword. You'll have to use coercion in the deriving property, but it'll behave exactly as it would if it were truly polymorphic (as long as you don't change the implementation).

P.S. static typing also allows for awesome IntelliSense support :cool:
 
Last edited:
Then continue developing in Smalltalk or produce your own language?

It comes down to the simple concept of... "using the correct tool for the job".

Not an option unfortunately. In this case, the right tool for the job is one that will translate from a WSDL web service to a COM library (via Interop)

Don't even get me started on the politics of that, and the very fact that Interop is there as a work around to the original faults of MS products :p
 
I'm not quite sure what you're trying to say here, but I think you're misunderstanding the nature of polymorphism in .NET. Fields are intentionally not polymorphic in a statically typed language because it doesn't make sense for them to be unless they're either read-only or write-only.
They are place holders for values.. ergo, variables. :)
The field on the derived class is hiding the field in the base class because in a statically typed language it is not possible to override it. This is not a limitation of static typing, but a semantic problem with what you're trying to do.
It's a semantic problem of not being able to do what I need to do. The extended/derived class is extending/deriving from the base class purely because of the need for that field to be of different type. All base functionality is identical, it is simply extended upon. Both by the derived class, and that of the type which is being overriden.
I'm not even sure what you'd be trying to achieve by overriding the field in a dynamically typed language anyway; there is no type specification on the field, so what is there to override? :confused:
I place my baggage on the floor, for a break. :)
Still, though, I'm not sure why you can't see the semantic problems with your goal. As I've said, static typing not only mandates type consistency, but it also introduces the notion of semantic consistency, which isn't present with dynamic typing. In specifying the type of a member, you're also – to some extent – specifying what it is and what it should do, which is why consistency is so important.
That's the crux of my argument/rant. I don't care what it should do, I don't care what it is called. If I want it to quack, and it quacks, then I don't care if it's a goose, duck, swan, or even an Elephant - just as long as it quacks when I want it to. :)
Again, I can't say I've ever come across typing problems like this in C#. Maybe your dynamic typing just makes you more lax in your approach to OOP :p
Anything but :)
Well that's just how nominal subtyping and statically typed languages work, sorry :/

Returning to the original problem, though, if the field is read-only, then you can make it a property with only a get accessor and then hide the base property with the the derived class's property using the new keyword. You'll have to use coercion in the deriving property, but it'll behave exactly as it would if it were truly polymorphic (as long as you don't change the implementation).

P.S. static typing also allows for awesome IntelliSense support :cool:
There are other ways to get IntelliSense outside of static typing. Again, more evangelism, Smalltalk has done just fine with this for years. :)
 
I don't think this is really going anywhere!

That's the crux of my argument/rant. I don't care what it should do, I don't care what it is called. If I want it to quack, and it quacks, then I don't care if it's a goose, duck, swan, or even an Elephant - just as long as it quacks when I want it to. :)

Well I care: what if an elephant's quack has catastrophic (or worse: subtly incorrect) consequences? I just prefer to know in advance if this might happen.

There's no right answer here. You just don't like this particular typing system, while I (and many others) do. Sucks for you I guess?

Anything but :)There are other ways to get IntelliSense outside of static typing. Again, more evangelism, Smalltalk has done just fine with this for years. :)

I'm not arguing against dynamic typing; indeed I use it on a daily basis and it works fine for me. In fact your own evangelism of Smalltalk has made me quite keen to try it out, but unfortunately my host doesn't support Seaside, and I can't see it surpassing C# for Windows app development, if only for C#'s ease of use, seemless integration with Windows, and support from MS.

Maybe it's because I'm very mathematically-minded, but I just find the rigourous nature of static typing to be natural and "right". Programming of any kind is closely linked to type theory, which is an aspect of maths. Maths is intrinsically strict in this respect, and so as I see it a program shouldn't compile if it's not consistent.

Besides, at the end of the day, you're the one who's attacking static typing and evangelizing your preferred typing system, not me!
 
Last edited:
I don't think this is really going anywhere!
I agree, I don't think it is either, but it's a healthy discussion, even if it does not provide a conclusion, it may help others come to their own. :)
Well I care: what if an elephant's quack has catastrophic (or worse: subtly incorrect) consequences? I just prefer to know in advance if this might happen.
How is an arbitrary interface going to stop that? If both elephant and duck implement "public void Quack()" and "IQuackable" how is that so safe against not implementing any thing and being dynamic? :)

There's no right answer here. You just don't like this particular typing system, while I (and many others) do. Sucks for you I guess?
That it does, whilst it also sucks for anyone else wanting to override the type on a property/field between types that do not have a parent interface. I'm above certain I'm not the only one. :)
I'm not arguing against dynamic typing; indeed I use it on a daily basis and it works fine for me. In fact your own evangelism of Smalltalk has made me quite keen to try it out, but unfortunately my host doesn't support Seaside, and I can't see it surpassing C# for Windows app development, if only for C#'s ease of use, seemless integration with Windows, and support from MS.
I'm glad you were tempted :) Yes, there is not much support for Seaside - and on a side note there is free hosting for non-commerical site at http://www.seasidehosting.st :)

Maybe it's because I'm very mathematically-minded, but I just find the rigourous nature of static typing to be natural and "right". Programming of any kind is closely linked to type theory, which is an aspect of maths. Maths is intrinsically strict in this respect, and so as I see it a program shouldn't compile if it's not consistent.
Now we're getting somewhere with this discussion. :) I'm not a mathematical minded person other than I am a very logical man. If something is going to break, I want it to break, so I can fix and learn. I do not want something to always alert me long in advance. This of course only applies to software, if I were building a house or something that's a different story entirely. As far as software is concerned, there is so much that cannot be detected at compile time (in terms of desired behaviour) then why even bother with such fallacies (in this case at least) as inconsistency - an inconsistency which is *purely* based on two of my objects not implementing an arbitrary label. :)
Besides, at the end of the day, you're the one who's attacking static typing and evangelizing your preferred typing system, not me!
I was actually only mentioning Smalltalk because frankly, it's the best I've ever used and ever likely to use. I really don't mean to start a comparison war, this is not what this thread is about. :) I actually do want to find a solution to this problem! :)
 
Back
Top Bottom