我可以将 T 传递给类构造函数吗
我有一个类,例如:
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;}
}
I have a class such as:
public MyClass
{
public myEnumType Status {get;set;}
public DataTable Result{get;set;}
}
Because DataTables suck I want to implement an object orientated approach. However I have existing code such as:
public interface IData
{
MyClass AddData(int i);
MyClass GetData(string Tablename);
}
I would like to use this interface but instead of returning a DataTable I want to return an object of some sort eg/Person class.
I did think of creating a new class that inherited MyClass like so:
public MyInheritedClass<T> : MyClass
{
public new T Result{get;set;}
}
However whenever you get data from a class that implements the interface you will have to cast the result of the methods from MyClass to MyInheritedClass. So I was wondering if there was a way of using the existing MyClass to put a constructor in that passes a generic type so I end up with something like
public MyClass
{
public MyClass(T MyObjectOrientatedClass)
{
MyOOClass = MyObjectOrientatedClass;
}
public myEnumType Status {get;set;}
public DataTable Result{get;set;}
public T MyOOClass {get;set;}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 C# 中,表达式的类型由编译时其组成部分的类型决定。这意味着像您的上一个示例(仅通过知道类的类型就无法知道属性的类型)之类的东西无法工作。
想象一下如果该类定义被编译。那么你就会遇到这个问题:
当然你可以使用
object
,但是你不会知道有关属性值的任何信息,因此你必须先进行强制转换,然后才能对其执行任何操作。解决您的原始问题,可以通过从现有的 IData 接口派生新的通用接口来以兼容的方式扩展现有类型(有一些粗糙的边缘):
In C#, the types of expressions are determined by the types of their constituent pieces at compile time. This means something like your last example (where the type of the property is unknowable just by knowing the type of the class) can't work.
Imagine if that class definition compiled. Then you have this problem:
Sure you could use
object
, but then you wouldn't know anything about the property value, so you'd have to cast before you could do anything with it anyway.Addressing your original issue, it is possible (with a few rough edges) to extend your existing types in a compatible fashion by deriving a new generic interface from your existing
IData
interface:如果不在尖括号中声明,则无法引用泛型类型参数,因此您必须拥有
IData
和/或MyClass
code> type,在这种情况下,您不需要将其指定为构造函数的参数。如果您无法更改这些类型,您仍然可以使用动态调度来避免显式转换。重载具有不同子类型的方法并使用动态表达式将方法解析推迟到运行时,它将自动为您转换为子类型:
You can't refer to a generic type parameter without declaring it in the pointy brackets, so you'll either have to have a
IData<T>
and/orMyClass<T>
type, in which case you won't need to specify it as a parameter to the constructor.If you can't change those types you can still avoid explicit casting by using dynamic dispatch. Overload a method with the different subtypes and use a dynamic expression to defer the method resolution to runtime, and it'll be automatically cast to the subtype for you:
为什么不创建一个通用接口,就像
我们甚至可以有一个通用实现一样:
Why not create a generic interface like
we can then even have a generic implementation:
虽然这是一个有点可怕的想法,但只要您想要放入 T 的内容可以装箱到 MyClass 中,您就可以编写一个像这样的方法......
相当恶心,但它允许您“封装”演员阵容。但实际上,我们正在讨论……
和……
之间的区别,我不确定我认为其中一个一定比另一个更好,并且可能会坚持使用演员表。
While it is a somewhat horrible idea, as long as what you wanted to put into T can be boxed into
MyClass
, you could write a method like...Pretty gross, but it would allow you to "encapsulate" the cast. In reality, though, we're talking about the difference between...
...and...
I'm not sure I think one of those is necessarily better than the other and would probably just stick with casts.