我有一个具有一个类型参数 (T) 的泛型类。我需要存储这些不同类型的通用对象的集合,因此我创建了一个通用类按照建议实现的接口here https://stackoverflow.com/questions/754341/adding-generic-object-to-generic-list-in-c。在迭代包含 Interface 对象集合的泛型列表时,我需要访问类型 T 的泛型类中的一个属性。到目前为止,我能够获取该值的唯一方法是使用反射调用方法。
interface ISomeClass {
//?
}
class SomeClass<T> : ISomeClass {
T ValueINeed { get; set;}
}
class ClassThatHasListOfGenericObjects{
List<ISomeClass> _l = new List<ISomeClass>();
public AddToList<T>(T someClass) : where T : ISomeClass {
_l.Add(someClass);
}
public SomeMethod(){
foreach(ISomeClass i in _l){
i.ValueINeed; //I don't know how to access the property in the generic class
}
}
}
在我看来,你有两个选择。最简单的选择是在接口上公开值(作为对象)(也可能是其类型)。看起来是这样的:
interface ISomeClass
{
object ValueINeed { get; set; }
// Only needed if you care about static type rather than using ValueINeed.GetType()
Type TypeOfValue { get; }
}
class SomeClass<T> : ISomeClass
{
public T ValueINeed { get; set; }
public Type TypeOfValue { get { return typeof(T); } }
object ISomeClass.ValueINeed { get { return ValueINeed; } set { ValueINeed = (T)value; } }
}
这样做的缺点是需要进行一些转换,并且您可能需要调用反射来对该值执行某些操作。它的优点是易于理解和实施。
另一种选择是编码一个“存在类型”,它真正代表一个SomeClass<T>
对于一些未知的T
(像一个SomeClass<?>
在爪哇)。这要复杂得多且难以遵循,但避免了任何强制转换:
interface ISomeClassUser<X>
{
X Use<T>(SomeClass<T> s);
}
interface ISomeClassUser
{
void Use<T>(SomeClass<T> s);
}
interface ISomeClass
{
X Apply<X>(ISomeClassUser<X> user);
void Apply(ISomeClassUser user);
}
class SomeClass<T> : ISomeClass
{
public T ValueINeed { get; set; }
public X Apply<X>(ISomeClassUser<X> user) { return user.Use(this); }
public void Apply(ISomeClassUser user) { user.Use(this); }
}
// Assumes you want to get a string out, use a different generic type as needed
class XmlUser : ISomeClassUser<string>
{
public string Use<T>(SomeClass<T> s)
{
string str = "";
// do your conditional formatting here, branching on T as needed
// ...
return str;
}
}
class ClassThatHasListOfGenericObjects
{
List<ISomeClass> _l = new List<ISomeClass>();
XmlUser user = new XmlUser();
public string SomeMethod()
{
string s = "";
foreach (ISomeClass i in _l)
{
s += i.Apply(user);
}
return s;
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)