泛型方法访问c#中的隐藏属性

时间:2017-07-27 10:25:02

标签: c#

我目前遇到了麻烦,我不知道如何解决它。

我有2个班级:

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

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

当我尝试访问B.MyParam时,当我有一个正确的类型时它会工作,但在我的大多数方法中我都有一个泛型类型 用:

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();
        }
    }
}

有办法吗? 提前谢谢。

编辑:似乎我想要的是:

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

2 个答案:

答案 0 :(得分:1)

你的代码没有任何意义。如果A继承自B,您需要A 覆盖您的媒体资源的基础实施。所以我假设你应该重新考虑你的继承链。

您可以使用override。因此,当您的variable - 参数属于您的基类(我将其重命名为A)时,您正在调用基本方法,如果它是派生实例(此处为B)你在调用覆盖:

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

编辑:虽然new引用了一个新成员(意外地)与基本成员具有相同的名称(和签名),但它有效地隐藏了基本成员。因此,您有效地拥有两个成员。指示应该使用哪个成员的唯一方法是将实例强制转换为需要实现的所需类。然而,这在某种程度上打破了泛型的目的,因为泛型成员必须知道类型参数可能的确切类型。

无论如何,这对我来说似乎是破碎的设计,因为你实际上正在创建一个具有另一个含义的新成员。所以你也应该给它一个新的名称

答案 1 :(得分:0)

根据您的通用方法,我认为您只需要一个界面。

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

你的课程。

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; }
    }
}

你的方法,不需要是通用的。

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

调用你的方法。

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