Passing derived objects in a constructure
This is a bit of a c开发者_StackOverflowonvoluted question, hopefully I can make it clear.
I am finding that this may not be possible, but am trying to see if anybody has a solution.
I have four classes, two are core classes and two are those core classes extended:
extUser
Extends coreUser
extSecurity
Extends coreSecurity
In the constructor for coreUser
you have this:
public coreUser(string id, ref coreSecurity cs)
When trying to extend coreUser
you would have this:
public extUser(string id ref extSecurity es) : base(id, ref es)
This fails because es is of type, extSecurity
and the base class expects a type of coreSecurity
. I've not found anyway to cast this to allow for me to override this base class in C#. In VB it works just fine.
As a note, I am, for the sake of this question, 100% unable to make changes to the core classes.
Ideas?
This is because arguments for ref
parameters have to have exactly the same type as the parameter, not just one that has a conversion available.
Do you really, really need the ref
part? Making a constructor take a ref
parameter is pretty unusual. Are you sure this isn't just a bit of confusion over parameter passing mechanisms? I know you've said that you can't change the "core" types, but you should at least look at changing them at some point in the future unless they're genuinely using this "ref" functionality. If they are making use of "ref" then it makes sense that it's not allowed... the coreUser
constructor could look like this:
public coreUser(string id, ref coreSecurity cs)
{
coreSecurity = new coreSecurity();
}
That would confuse your extUser
constructor, wouldn't it? es
would then refer to an object which wasn't an extSecurity
...
(Along similar "that's weird" lines - are your types really camelCased? The .NET conventions are for types to be PascalCased...)
If you can really only change the extUser
constructor, then as Oded says you can change the parameter type to coreSecurity
- and then if you need it as an extSecurity
, you can
cast it:
public extUser(string id, ref coreSecurity cs) : base(id, ref cs)
{
extSecurity es = (extSecurity) cs;
// Use es here
}
Of course, that will throw an exception if cs
refers to an object which isn't an extSecurity
by the time the base constructor has returned...
I suggest you to analyze your code inside the constructors bodies to see why do you need the coreSecurity
and extSecurity
to be reference parameters.
ref
is used to manipulate a value type (i.e. reference, structs or ints etc). This alone shows an immense misuse of the constructor (Constructor does real work, it's java but applies as well). Constructors are there to construct an object, for which you never need a ref parameter. I know this doesn't really answer your question, but your code is seriously flawed.
ref keyword
Generally spoken, the ref keyword allows arguments to be passed by reference. This means, changes to the arguments will be reflected outside the method's scope.
Example 1: Passing a ref int
public class Test
{
public void TestMethod (ref int input)
{
input = 2;
}
public void Run()
{
int testVar = 1;
TestMethod(ref testVar);
//testVar is now 2
}
}
Example 2: Passing a ref string Normally, if you pass a string (or any other reference type) in to a method, you can't change the object itself.
public class Test
{
public void TestMethod (ref string input)
{
input = "changed";
}
public void Run()
{
string testVar = "original";
TestMethod(ref testVar);
//testVar is now "changed"
}
}
With the ref argument, it allows you to change the object itself, not just its fields and properties. The ref argument on a referenceType allows you to modify the reference itself (by assigning a new object to it), not just the contents of the reference (see msdn).
精彩评论