我可以将 T 传递给类构造函数吗

发布于 2024-12-05 23:18:09 字数 894 浏览 0 评论 0原文

我有一个类,例如:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

罪歌 2024-12-12 23:18:09

在 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);
}

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:

// What would you use as the type of this variable?
??? val = GetMyClassFromSomewhere().MyOOClass;

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:

public interface IData<T> : IData
{
    new MyInheritedClass<T> AddData(int i);
    new MyInheritedClass<T> GetData(string Tablename);
}
与往事干杯 2024-12-12 23:18:09

如果不在尖括号中声明,则无法引用泛型类型参数,因此您必须拥有 IData 和/或 MyClass code> type,在这种情况下,您不需要将其指定为构造函数的参数。

如果您无法更改这些类型,您仍然可以使用动态调度来避免显式转换。重载具有不同子类型的方法并使用动态表达式将方法解析推迟到运行时,它将自动为您转换为子类型:

void DoSomethingWith(Person p) { ... }
void DoSomethingWith(AnotherClass x) { ... }

void DomSomtheingWithMyInheritedClass(MyClass x)
{
   DoSomethingWith((dynamic) x.Result);
}

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/or MyClass<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:

void DoSomethingWith(Person p) { ... }
void DoSomethingWith(AnotherClass x) { ... }

void DomSomtheingWithMyInheritedClass(MyClass x)
{
   DoSomethingWith((dynamic) x.Result);
}
空心空情空意 2024-12-12 23:18:09

为什么不创建一个通用接口,就像

public interface IData<T>
{
    T AddData(int i);
    T GetData(string Tablename);
}

我们甚至可以有一个通用实现一样:

public class MyGenericClass<T> : IData<T>
{
} 

Why not create a generic interface like

public interface IData<T>
{
    T AddData(int i);
    T GetData(string Tablename);
}

we can then even have a generic implementation:

public class MyGenericClass<T> : IData<T>
{
} 
感受沵的脚步 2024-12-12 23:18:09

虽然这是一个有点可怕的想法,但只要您想要放入 T 的内容可以装箱到 MyClass 中,您就可以编写一个像这样的方法......

public T GetResult<T>() where T : MyClass
{
    return (T)Result;
}

相当恶心,但它允许您“封装”演员阵容。但实际上,我们正在讨论……

var result = (DerivedMyClass)obj.Result;

和……

var result = obj.GetResult<DerivedMyClass>();

之间的区别,我不确定我认为其中一个一定比另一个更好,并且可能会坚持使用演员表。

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...

public T GetResult<T>() where T : MyClass
{
    return (T)Result;
}

Pretty gross, but it would allow you to "encapsulate" the cast. In reality, though, we're talking about the difference between...

var result = (DerivedMyClass)obj.Result;

...and...

var result = obj.GetResult<DerivedMyClass>();

I'm not sure I think one of those is necessarily better than the other and would probably just stick with casts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文