【问题标题】:Derived Generic Class Doesn't See Parent's Variables派生的泛型类看不到父级的变量
【发布时间】:2019-10-04 03:02:12
【问题描述】:

我试图将类与其他设置或更改类中的数据隔离开来。我选择使用一个名为 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();
            }
        }
    }
}

【问题讨论】:

  • 请注意您的标题具有误导性 - 您的泛型类没有父类

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


【解决方案1】:

ConcreteGeneric&lt;T&gt; 类中的代码必须与 any T 一起使用,您可能决定提供它。由于您已将 T 限制为 Parent,这意味着您可以访问任何 Parent's 属性。

您可以说“我希望能够在此处查看派生类参数”,但是如果您创建了一个 ConcreteGeneric&lt;DerivedA&gt; 怎么办?那么那里就不会有任何DerivedBString 属性供您访问。

您可以做的是将您的T 直接暴露在ConcreteGeneric&lt;T&gt; 中:

public T Item { get; }

然后您就可以将您的genericType 转换为ConcreteGeneric&lt;DerivedA&gt;,并访问.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();
}

【讨论】:

  • 你的意思是string s = conceteDerivedA.Item.DerivedAString;
  • 没问题。很好的答案。
  • canton7:非常感谢您的回复。我不得不承认我对 C# 有点陌生。我对某一点感到困惑。当你说: var concreteDerivedA = (ConcreteGeneric)genericType;我担心 DerivedA 部分是括号中的类型。我可以看到 30 个类将作为 进入 Concrete 类,我不能对所有这些类进行“if-else if”。也许您可以重写您将其放置的位置,而不是仅针对 DerivedA 而是针对 T。您理解我的困惑吗?再次感谢您的帮助!!
  • 对此有两个答案。如果所有这些类都不同并且具有不同的属性,那么您将不得不使用不同的代码来处理它们。没有办法解决这个问题。您不能拥有完全不同的 DerivedA 和 DerivedB 类型,然后编写以相同方式处理它们的代码。另一方面,如果您的派生类型有一些共同点,那么您可以编写指定这些通用属性的接口/基类,然后您可以编写访问它们的通用代码。总的来说,虽然我真的不明白你在这里想要做什么。
  • 好的,也许我没有正确地问我的问题。对不起。我想要做的是通过传入一个 JSON 字符串来设置我在 Parent 和所有抽象派生类中的所有属性。那么,如果我有一个抽象方法,例如: public abstract void SetJSONString(string jsonString);然后我想在 Concrete 类中实现它,然后让它尝试从这个字符串中设置 DerivedA 和 DerivedB 中的所有变量。我正在尝试这个但失败了。谢谢。
猜你喜欢
  • 2010-09-20
  • 1970-01-01
  • 2014-03-22
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-09
相关资源
最近更新 更多