我有一个类如:
public MyClass
{
public myEnumType Status {get;set;}
public DataTable Result{get;set;}
}
因为DataTables很糟糕,我想实现面向对象的方法。但是我有现有的代码,例如:
public interface IData
{
MyClass AddData(int i);
MyClass GetData(string Tablename);
}
我想使用这个接口,但我没有返回一个DataTable,而是想返回某种对象,例如/ Person类。
我确实想过创建一个继承MyClass的新类,如下所示:
public MyInheritedClass<T> : MyClass
{
public new T Result{get;set;}
}
但是,无论何时从实现接口的类中获取数据,都必须将方法的结果从MyClass转换为MyInheritedClass。所以我想知道是否有一种方法可以使用现有的MyClass来构建一个传递泛型类型的构造函数,所以我最终会得到像
这样的东西public MyClass
{
public MyClass(T MyObjectOrientatedClass)
{
MyOOClass = MyObjectOrientatedClass;
}
public myEnumType Status {get;set;}
public DataTable Result{get;set;}
public T MyOOClass {get;set;}
}
答案 0 :(得分:1)
如果没有在尖括号中声明它,则无法引用泛型类型参数,因此您必须拥有IData<T>
和/或MyClass<T>
类型,在这种情况下您赢了不需要将它指定为构造函数的参数。
如果您无法更改这些类型,则仍可以使用动态调度来避免显式投射。使用不同的子类型重载方法并使用动态表达式将方法解析推迟到运行时,它将自动转换为子类型:
void DoSomethingWith(Person p) { ... }
void DoSomethingWith(AnotherClass x) { ... }
void DomSomtheingWithMyInheritedClass(MyClass x)
{
DoSomethingWith((dynamic) x.Result);
}
答案 1 :(得分:1)
在C#中,表达式的类型由编译时其组成部分的类型决定。这意味着类似于你的最后一个例子(仅通过知道类的类型,属性的类型是不可知的)无法工作。
想象一下,如果编译了这个类定义。然后你有这个问题:
// What would you use as the type of this variable?
??? val = GetMyClassFromSomewhere().MyOOClass;
当然你可以使用object
,但是你不会对属性值有任何了解,所以无论如何你都必须先进行投射。
通过从现有IData
界面派生新的通用界面,可以(通过一些粗略的边缘)以兼容的方式扩展现有类型:
public interface IData<T> : IData
{
new MyInheritedClass<T> AddData(int i);
new MyInheritedClass<T> GetData(string Tablename);
}
答案 2 :(得分:0)
为什么不创建像
这样的通用界面public interface IData<T>
{
T AddData(int i);
T GetData(string Tablename);
}
我们甚至可以有一个通用的实现:
public class MyGenericClass<T> : IData<T>
{
}
答案 3 :(得分:0)
虽然这是一个有点可怕的想法,只要你想把它放到T中就可以装入MyClass
,你可以编写一个类似......的方法。
public T GetResult<T>() where T : MyClass
{
return (T)Result;
}
相当粗略,但它可以让你“封装”演员阵容。但实际上,我们正在谈论......之间的区别。
var result = (DerivedMyClass)obj.Result;
...和...
var result = obj.GetResult<DerivedMyClass>();
我不确定我认为其中一个肯定比另一个好,而且可能只是坚持演员。