Erwan Joly
Erwan Joly

Reputation: 611

generic method access hidden property in c#

I'm currently having trouble and I have no clue how to fix it.

I have 2 classes:

class A 
{
 public string MyParam { get; set; }
}

class B : A
{
  public new string MyParam { get { return base.MyParam != null ? base.MyParam.Substring(1) : null; } }
}

When I try to access the B.MyParam it works when I have a the correct type, but in most of my methods I have a generic type with :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public class A
        {
            public string MyParam { get; set; }
        }

        public class B : A
        {
            public new string MyParam
            {
                get { return base.MyParam != null ? base.MyParam.Substring(1) : null; }
            }
        }
        public static void MyMethod<T>(T variable) where T : A
        {
            Console.WriteLine(variable.MyParam);//this print hello
            Console.WriteLine((variable as B).MyParam);//this print ello (exactly what i want)
            Console.WriteLine(typeof(T)); // this print ConsoleApplication1.Program+A
            Console.WriteLine(variable.GetType()); // this print ConsoleApplication1.Program+B

            // so i need something like that

            Console.WriteLine((variable as variable.GetType()).MyParam); // this line is invalid
        }

        static void Main(string[] args)
        {
            A a = new B();
            a.MyParam = "Hello";
            Console.WriteLine(a.GetType());
            MyMethod(a); 
            Console.ReadKey();
        }
    }
}

Is there a way to do it? Thank you in advance.

EDIT: it seems that what i want is :

 dynamic variable2 = Convert.ChangeType(variable, variable.GetType());
 Console.WriteLine(variable2.MyParam); 

Upvotes: 1

Views: 1770

Answers (2)

Derrick Moeller
Derrick Moeller

Reputation: 4960

Based on your generic method, I think all you need is an interface.

public interface IMyParam
{
    string MyParam { get; set; }
}

Your classes.

class A : IMyParam
{
    public virtual string MyParam { get; set; }
}

class B : A
{
    public override string MyParam
    {
        get { return base.MyParam != null ? base.MyParam.Substring(1) : null; }
    }
}

And your method, won't need to be generic.

public void MyMethod(IMyParam variable)
{
    // Your logic here, for example.
    Console.WriteLine(variable.MyParam);
}

Calling your method.

A a = new A();
a.MyParam = "Hello";

B b = new B();
b.MyParam = "Hello";

A ab = new B();
ab.MyParam = "Hello";

MyMethod(a); // Prints Hello
MyMethod(b); // Prints ello
MyMethod(ab); // Prints ello

Upvotes: 0

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37115

Your code doesn´t make any sense. If A inherits from B you´ll need A to override the base-implementation for your property. So I´ll assume you should rethink your inheritance-chain.

You can use override for this. Thus when your variable-parameter is of your base-class (I renamed that to A) you´re calling the base-method, if it´s a derived instance (here B) you´re calling the override:

class A
{
    public virtual string MyParam { get; }
}

class B : A // note here that B derives from A, not the other way round
{
    public override string MyParam 
    { 
        get { return base.MyParam != null ? base.MyParam.Substring(1) : null; },
        set { ... }
    }
}

EDIT: While new intrduces a new member which (accidentally) has the same name (and signature) as the base-member it effectivly hides the base-member. Thus you effectivly have two members. Your only way to indicate which member should be used is by casting your instance to the desired class from which you need the implementation. However this somehow breaks the purpose of generics as the generic member has to know the exact types that are possible for the type-parameter.

Anyway this seems like broken design to me, as you´re actually creating a new member which has another meaning. So you should also give it a new name.

Upvotes: 1

Related Questions