我正试图让其他类与其他类隔离,以设置或更改类中的数据。我选择使用一个称为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();
}
}
}
}
答案 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();
}