|
Func<t> is only one thing that could be placed in T. A Queue<t> would be equally qualified, as it has a candidate for calling that results in T.
|
|
|
|
|
Hello experts,
I have an inheritance issue that can be better explained in code than in text:
public abstract class AbstractBase
{
protected abstract void DoSomething();
}
public class FirstDerived : AbstractBase
{
protected override void DoSomething()
{
int foo = 5;
}
}
public class SecondDerived : AbstractBase
{
protected override void DoSomething()
{
int bar = 3;
}
private void DoAnotherThing()
{
FirstDerived firstDerived = new FirstDerived();
firstDerived.DoSomething();
}
}
The mentioned error in German reads
Auf den geschützten Member "AbstractBase.DoSomething()" kann nicht über einen Qualifizierer vom Typ "FirstDerived" zugegriffen werden. Der Qualifizierer muss vom Typ "SecondDerived" (oder von ihm abgeleitet) sein.
In English that would mean something like
A qualifier of type "FirstDerived" cannot access the protected member "AbstractBase.DoSomething()". The qualifier has to be of type "SecondDerived" (or derived thereof).
Why would that be?
Do I have to change from protected to internal ?
Ciao,
luker
|
|
|
|
|
Nothing to do with abstract, but the visibility of DoSomething(). It's protected meaning only visible to derived classes. You are trying to call it from outside, therefore it would need to be public.
Regards,
Rob Philpott.
|
|
|
|
|
Though I daresay you could use:
AbstractBase firstDerived = new FirstDerived();
firstDerived.DoSomething();
Now, because you can* access DoSomething in abstract base and because the function is virtual, the call will end up at FirstDerived::DoSomething.
However, this structure is quite odd and you should adjust your design a bit rather than hacking around it.
*) Actually, I'm not 100% sure, but I think this works
|
|
|
|
|
|
It's odd and should be redesigned because it breaks encapsulation. That function is protected for a reason. The code is creating a new object that is different from itself and then tries to call protected members - that is obviously an error. They share the same base class so it can bypass this restriction via a sort of cheat.
However, the idea behind the encapsulation / protected was that external sources do NOT have access to that function, and there must have been a reason why this is so. The fact that they share a base does not make it right (in terms of Object Oriented design) to bypass the rules.
Derived classes can access protected base members to support derivation, but a side-effect of this rule is that they can indirectly access protected members of classes they have no valid access to.
Like it has been suggested, if that function needs to be called, make it public, or internal.
|
|
|
|
|
|
Mark Nischalke wrote: However, I disagree that it is odd
Certainly looks wrong to me. Circumventing access on purpose mostly indicates a design problem. Doing it accidentally if of course an accident.
Mark Nischalke wrote: It's not an error
The compiler would seem to disagree with you.
|
|
|
|
|
Mark Nischalke wrote: Don't you think this would have been a better response to the OP than "this structure is quite odd and you should adjust your design"? How would they have know what odd meant or how it should be redesigned in your opinion?
You're just sulking because you disagree.
At any rate, maybe it'd be a better response to the OP if I explicitly explained the meaning of every word that is over 6 letters; after all, how are they supposed to know all those difficult words?
Why don't I? This has to do with estimating someone's level of knowledge and adjusting your answer in response. Obviously, I have a higher estimate of the OP's knowledge in this than you do. In the same way that I don't give the definition of every English word that is over 6 letters, I don't give explanation of what the word 'odd' means in this context (it was logical to me). About adjusting the design, well... like you said yourself, it's an example the OP gave, so I can't say anything relevant about that (at least, not that hadn't already been said by others). I'd need to know the actual design, and even then there might be multiple 'good' designs to go from.
Secondly, I refrained from a more elaborate explanation, because I preferred to wait and see if the OP is at all interested, before I waste time writing pages of info no one is ever going to read or care about. I find that people who are interested usually either understand it, or ask for explanation. If they're not interested, then there's no point in typing more than a succinct response in the first place.
Either way, you're very belittling in your response. Rather than appreciating a decent response, you snap out like I offended you personally. I find it hard to understand what warrants such a reaction. Therefore, I might be less than courteous in my response here; you reap what you sow (goes for me too).
To a more insightful point:
Mark Nischalke wrote: You mean this line?
FirstDerived firstDerived = new FirstDerived();
Well, yes, of course it is different. It is being called in class SecondDerived. I don't see anything odd about that.
Well, for one thing, you missed the line that was odd, in the quote. At any rate, I will attempt to explain. Considering the following example, which is design-wise equivalent to the original:
class Base
{
protected abstract void DoSomething();
}
class Derived : Base
{
protected override void DoSomething() {...}
private void SomethingElse()
{
CompletelyDifferent otherObject = new CompletelyDifferent();
otherObject.SomeFunction();
}
}
class CompletelyDifferent
{
protected void SomeFunction() {...}
}
Now I hope you agree that the line with the Error is an error for a good reason. And that trying to circumvent this error in any way is odd (or at least, bad practice).
The equivalence between this and the case where the two classes share a common base, from a design point of view, comes from the fact that having a shared element in no way means they have private access to each other. So, in our discussion of design philosophy, we are as well talking about the original example as this one.
Consider, for instance, a base Stream class and then a derived FileStream and an InternetStream. Even though they share a common base (Stream), they are totally unrelated, as FileStream knows nothing of streaming from the internet and InternetStream knows nothing of files. It would be extremely odd if FileStream then could have privileged (protected) access to a method InternetStream, under the nomer 'but they share a common base'. They are completely different and thus should be treated as such.
Sure, the 'hack' might allow it (not entirely sure that it does, but we're saying it does for the discussion), but it is a still a violation of the principles of encapsulation. It's protected for a reason.
Now of course, a fix to the above example would be to make SomeFunction public (or internal) so it can be properly accessed, but whether this is appropriate depends on the actual situation.
Mark Nischalke wrote: It's not an error. It is someone trying to learn, giving an example and asking for an explaination.
I was, of course, referring to the circumvention of the protected access specifier, which is an error.
|
|
|
|
|
|
Quite honestly Mark having read this thread now I think this is completely unwarranted and I've given you a 1 vote in consequence.
If instead of saying "Please elaborate why you think it odd and how it should be redesigned." you'd said something like "I'm not sure I agree. Could you elaborate on why you think it odd and how it might be redesigned?" you might have headed off the entire confrontation.
Anna
Tech Blog | Visual Lint
"Why would anyone prefer to wield a weapon that takes both hands at once, when they could use a lighter (and obviously superior) weapon that allows you to wield multiple ones at a time, and thus supports multi-paradigm carnage?"
|
|
|
|
|
I agree that Mark is succinct, perhaps even brusque, but he did not write a single uncivil or rude word. He asked for information, and he pointed out that one response was better than another at achieving that goal.
From my perspective, if one of my clients had told me what Mark did, I would try to be brief and succinct in my answer as well.
Come on guys, have some coffee and chill.
|
|
|
|
|
|
I was not offended that he asked for explanation in his first post; he was sort of right - I was being (deliberately) short there.
I just felt stabbed in the back for being talked to in a condescending way when I did post the information. And it was not what he said, but how he said it. The general tone matters a lot. If someone asks if you could get them a drink by "Could you get me a drink?" then you most likely will, but at any rate you're not at all offended. Asking "Get me a drink" holds the same request, but stated rudely. There is no uncivil or rude word in that sentence, but I do think I should have a right to be offended.
In the same way, the way his post was stated offended me.
An important aspect of a community like this, to me, is the atmosphere of learning and tolerance. I usually try my best to preserve and honor that.
And it did indeed feel to me (as also noted in the other post) that Mark was pulling ranks on me. I'm bad when it comes to taking that
I do feel like we (me and Mark) might have both been had by the language barrier. It's quite possible (and I am hoping) that he did not mean to be so brisk as he sounded to me.
At any rate, I've supplied CP with enough forum-drama for a while
|
|
|
|
|
Mark Nischalke wrote: Yours is not the attitude we want here on CP. If you can't comment politely or don't have the time to adequate respond then please don't visit here.
Like I said, you reap what you sow. And this goes both way.
You were plainly being rude in being condescending towards me and my explanation. Under some guise of decency you ask me to elaborate, and then when I do you make an under-the-belt stab.
So please, do also read that nice thread you linked and see if you understand it yourself.
If you truly question my attitude, then I suggest you look up some of my other responses and make your judgement then. I am well aware of proper etiquette. I just don't like being flamed for my effort.
If you have a problem with my explanation, then tell me in a normal way, and we can discuss. As I've tried to, between all these flame-war posts. I explained my reasoning and am always well open to comments and critics.
|
|
|
|
|
Don't worry. I did not in any way feel offended by any one of your posts.
And even now, re-reading them, I can't find why I should have.
Ciao,
luker
|
|
|
|
|
MicroVirus wrote: that external sources do NOT have access to that function I didn't realize that different branches of an inheritance tree are treated that way. Thanks a lot for pointing this out.
Ciao,
luker
|
|
|
|
|
Actually, I tried that (*) prior to posting my question. It didn't work.
Ciao,
luker
|
|
|
|
|
Ahh okay. I'm glad to hear it didn't work
I wasn't sure about how strict C++ and C# would be about it, but you are right: they both (rightly) don't allow it.
|
|
|
|
|
The DoSomething() method is protected and cannot be accessed from outside the class and its subclasses. Make it internal , protected internal or public .
modified on Saturday, August 27, 2011 6:08 AM
|
|
|
|
|
Hi, Luker;
The related MSDN help topic for the similar compiler error I receive for the example at http://msdn.microsoft.com/en-us/library/s9zta243.aspxm, is:
"A derived class cannot access protected members of its base class through an instance of the base class. An instance of the base class declared in the derived class might, at run time, be an instance of another type that is derived from the same base but is not otherwise related to the derived class. Because protected members can be accessed only by derived types, any attempts to access protected members that might not be valid at run time are marked by the compiler as not valid."
If I'm following this explanation correctly, methods or member functions declared as protected can only be accessed by an immediate descendant of the base class. In the example above, since SecondDerived does not inherit its structure and behavior from FirstDerived, FirstDerived.DoSomething() cannot be called as the language is enforcing the scope and access of the protected method DoSomething(). Even if AbstracstBase.DoSomething() wasn't declared as abstract, the restricted access of the protected qualifier takes precedence.
Moreover, I don't think using the internal qualifier would help, as the compiler treats this as an error, in which the derived class, FirstDerived, was trying to change the access on a method that was inherited and declared as protected in the AbstractBase class. The internal keyword, in conjunction with a correctly defined assembly attribute, can only allow the runtime to access internal methods between friend assemblies. This approach for the friend qualifier seems specific to .NET, and unfortunately, is not the same as a friend function in C++.
Is it possible to provide an additional method in FirstDerived that would correctly expose and allow a call to FirstDerived.DoSomething() on behalf of the FirstDerived's consumer, or, could having the common polymorphic behavior of DoSomething() be expressed and implemented using an Interface instead?
I hope this was of help. If I missed something in your question, or incorrectly stated anything with regards to the use and application of the protected and internal keywords, please let me know.
Best Regards...
Bill
|
|
|
|
|
My apologies for any redundancies or oversights for the previous posts on my part....
Bill
|
|
|
|
|
Hi there,
I want to add "CorelDraw" file or "Flash" file into My C# Application,but I don't know
How do I Add these files into My App?
It is very importance for me,
Please Guide me!
Thank very much.
|
|
|
|
|
Coreldraw has a .Net API called the CorelDRAW 15.0 Type Library or the Vector Graphics Core 15.0 Type Library. These can be referenced in the COM tab when you try add a reference in Visual Studio. Good Luck!
Live for today. Plan for tomorrow. Party tonight!
|
|
|
|
|
Hi
Thanks very much!
May you tell me about adding "Flash" file into C# Application?
I need more Information about relation Graphic softwares(for example:Corel Draw or Flash) and
Applicatio(C#).
I want that my application recognizes clickes of user on an area of "CorelDraw",
for example :I draw map of world by Corel and while the user clickes on area(for example:Asia),
the color of this area changes.
my idea is possible or impossible by C#?
I work by C# 2005.
|
|
|
|
|