views:

64

answers:

3

This is a bit of a convoluted 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?

+2  A: 

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...

Jon Skeet
A: 

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.

Rafa Castaneda
A: 

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).

Femaref
ref can be used with reference types too. The two concepts are mostly orthogonal. See Dictionary.TryGetValue for example, bearing in mind that out is very similar to ref.
Jon Skeet
Yes, it can be used with reference types as well, as I wrote (a reference itself is a value type, so a ref referenceType is a reference to a reference), which allows you to assign a new object to the parameter and this will be reflected outside the method. Out parameters are something different in this case.
Femaref
While I see what you're trying to say, IMO calling a reference a value type is very confusing. How can I get the Type object associated with this supposed type? If someone doesn't understand what ref means, I think your answer is more likely to confuse than illuminate. I suspect that ref isn't needed here, but not necessarily because the constructor is doing too much work.
Jon Skeet
Yup, the word choice might be problematic. I'll try to explain further.
Femaref
Rather than "as references" I'd just use "by reference" - less confusing than overloading "reference" as a noun IMO.
Jon Skeet