派生的通用类看不到父母的变量

时间:2019-05-16 19:16:54

标签: c# proxy abstract-class derived-class

我正试图让其他类与其他类隔离,以设置或更改类中的数据。我选择使用一个称为Parent的抽象基类,然后使用两个名为DerivedA和DerivedB的派生抽象类。然后,使用Assembly,从Parent获取派生的抽象类。然后,我使用泛型派生一个具体的类ConcreteGeneric,以希望填充抽象类的值。

我遇到的问题是,当我进入具体的类时,我没有访问权限(请参见)父类成员/属性。也许这种设计是错误的,但这是我想解决的理想方法。任何帮助将不胜感激...并保存掉落在我头上的头发。 ;)

已附加代码。

我已经在代码中记录了我想要的内容。为了能够访问和查看父类中的公共变量。

using System;
using System.Linq;
using System.Reflection;

public abstract class Parent
{
    public string Name { get; set; }
    public string Comment { get; set; }
}

public abstract class DerivedA : Parent
{
    public string DerivedAString { get; set; }
}

public abstract class DerivedB : Parent
{
    public string DerivedBString { get; set; }
}

public class DerivedFromA : DerivedA
{
    public string DerivedFromAString { get; set; }
}

public class ConcreteGeneric<T> where T : Parent
{
    private string _jsonString = "";
    public string HeaderString
    {
        get
        {
            return _jsonString;
        }
        set
        {
            /// I want to be able to see the Derived classes parameters 
            /// here.  Like   'DerivedB.DerivedBString'  if T is type DerivedB 
            _jsonString = value;
        }
    }
}

public class RunItClass
{
    public static void Main()
    {
        Type[] types = Assembly.GetAssembly(typeof(Parent)).GetTypes();
        foreach (Type type in Assembly.GetAssembly(typeof(Parent)).GetTypes()
            .Where(myType => myType.IsAbstract && myType.IsSubclassOf(typeof(Parent))))
        {
            var genType = typeof(ConcreteGeneric<>).MakeGenericType(type);
            Type genericType = (Type)genType;

            object genericInstance = Activator.CreateInstance(genericType);
            dynamic dynamicObj = Convert.ChangeType(genericInstance, genericType);

            /// Note that when I drop into the 'set' method on this dynamic object, I cannot see the 
            /// paramters of the parent class, which is 'DerivedA' on the first item in this loop. 
            dynamicObj.HeaderString = "Testing";

            // Testing here
            if (genericType == typeof(ConcreteGeneric<DerivedA>))
            {
                // ?? I CANNOT see all of the variables in 'DerivedA' ??
                ConcreteGeneric<DerivedA> da = (ConcreteGeneric<DerivedA>)genericInstance;

                /// I CAN see all of the variables in 'DerivedA' and also 'Parent'.  This is what I
                /// am after, but I want to be able to use the ConcreteGeneric<![CDATA[>]]> to accomplish this.
                /// Please help.  :)
                DerivedFromA dfa = new DerivedFromA();

                Console.WriteLine();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

ConcreteGeneric<T>类中的代码必须与 any T配合使用,您可以决定提供它。由于您已将T限制为Parent,这意味着您可以访问Parent's的任何属性。

您可以说“ 我希望能够在这里看到派生类参数”,但是如果您创建了ConcreteGeneric<DerivedA>怎么办?这样一来,您将无法访问任何DerivedBString属性。

您可能可以做的就是将T直接暴露在ConcreteGeneric<T>内部:

public T Item { get; }

然后,您就可以将genericType强制转换为ConcreteGeneric<DerivedA>,并访问.Item

var concreteDerivedA = (ConcreteGeneric<DerivedA>)genericType;
string s = conceteDerivedA.Item.DerivedAString;

剩下的问题是如何设置Item。如果强制其必须具有无参数构造函数,则可以执行以下操作:

public class ConcreteGeneric<T> where T : Parent, new()
{
    public T Item { get; } = new T();
}