从泛型类派生的类中访问派生类型的属性

huangapple go评论73阅读模式
英文:

Accessing property of derived type in a class derived from a generic class

问题

我对C#还很陌生,无法理解这个问题。

我有两个类,它们都派生自一个泛型类,其中T派生自BackgroundWorker(如下所示)。如何在另一个类中有一个字段,能够容纳这两个派生类之一,并访问派生的BackgroundWorker字段?我需要能够订阅派生BackgroundWorker的事件,并发出CancelAsync等命令...

我有一个泛型类:

public class GenericClass<T> where T : BackgroundWorker
{
    public T BgWorker;
}

并从中派生了两个类:

public class DerivedOne : GenericClass<BackgroundWorkerOne>
{ }

public class DerivedTwo : GenericClass<BackgroundWorkerTwo>
{ }

其中:

public class BackgroundWorkerOne : BackgroundWorker
{ }

public class BackgroundWorkerTwo : BackgroundWorker
{ }

然而,我如何在另一个类中创建一个字段/属性,能够根据某些其他变量来容纳DerivedOne或DerivedTwo之一?

我尝试过

public class AnotherClass
{
   public GenericClass<BackgroundWorker> Derived;

   public void DoSomething()
   {
      Derived = new DerivedOne();
   }
}

但我得到了"无法隐式转换类型 'DerivedOne' 到 'GenericClass'"错误。进行强制转换

Derived = (GenericClass<BackgroundWorker>)new DerivedOne();

也不起作用。

如上所述,无论Derived是DerivedOne还是DerivedTwo,我都希望能够订阅Derived.BgWorker中的事件。

在这里使用泛型是否是最佳选择?或者是否有其他路径(接口、遮蔽或其他方法)会更好?任何帮助将不胜感激!

编辑

我发现,正如在将泛型强制转换为泛型中所指出的,我的方法实际上并不可行。谢谢你的澄清。我上面展示的代码只是我迄今为止尝试过的,不一定是代码发展的固定方向。

此外,我的问题更多地是关于找到一种方法来从同一个基类中访问BackgroundWorker(在不同类中具有不同类型的属性)。

有什么适当的替代方法来访问Derived属性的BackgroundWorker(无论是BackroundWorkerOne还是BackgroundWorkerTwo)属性?是否有可能这样做,还是我应该重新考虑我的概念?

英文:

I'm still new to C# and cannot wrap my head around this issue.

I have a two classes deriving from a generic class with T deriving from BackgroundWorker (see below). How can I have a field in another class that is able to hold either of the two derived classes and access the field with the derived BackgroundWorker? I need to be able to subscribe to the derived BackgroundWorker's events and issue e.g. CancelAsync command...

I have a generic class:

public class GenericClass&lt;T&gt; where T : BackgroundWorker
    {
        public T BgWorker;
    }

and derive two classes from it:

public class DerivedOne : GenericClass&lt;BackgroundWorkerOne&gt;
    { }

public class DerivedTwo : GenericClass&lt;BackgroundWorkerTwo&gt;
    { }

where:

public class BackgroundWorkerOne : BackgroundWorker
    { }

public class BackgroundWorkerOne : BackgroundWorker
    { }

However, how can I make a field/property in another class that is able to hold either DerivedOne or DerivedTwo depending on some other variable?

I have tried

public class AnotherClass
{
   public GenericClass&lt;BackgroundWorker&gt; Derived;

   public void DoSomething()
   {
      Derived = new DerivedOne();
   }
}

But I get the "Cannot implicitly convert type 'DerivedOne' to 'GenericClass&lt;BackgroundWorker&gt;'" error. Casting it

Derived = (GenericClass&lt;BackgroundWorker&gt;)new DerivedOne();

does not work either.

As mentioned, I would like to subscribe to the events in Derived.BgWorker regardless if the Derived is of type DerivedOne or DerivedTwo.

Is using generics here the best option? Or would another path (interface, shadowing or something else entirely) be a better solution?

Any help would be appreciated!

EDIT

I see that my approach, as has been pointed out in Cast Generic&lt;Derived&gt; to Generic&lt;Base&gt;, is not really feasible. Thank you for that clarification. The code I've shown above is only what I have tried so far, not necesarrily a fixed direction in which the code has to develop.

Furthermore, my question was more geared towards finding a way to access the BackgroundWorker (property with varying types in different classes) from the same base class.

What would be a suitable alternative to be able to access the BackgroundWorker (wheather BackroundWorkerOne or BackgroundWorkerTwo) property of the Derived property? Is there a possiblity to do so or should I rethink my concept?

答案1

得分: 1

也许协变性是您的代码中缺少的部分?
您可以拥有这个接口

public interface IGenericClass<out T> where T : BackgroundWorker
{
    T BackgroundWorker { get; }
}

然后您可以像这样使用这个接口

public class AnotherClass
{
   public IGenericClass<BackgroundWorker> Derived;

   public void DoSomething()
   {
      Derived = new DerivedOne();
   }
}

public class DerivedOne : IGenericClass<BackgroundWorkerOne>
{
    public BackgroundWorkerOne BackgroundWorker { get; }
}
英文:

Maybe covariance is what is missing in your code ?
You can have this interface

public interface IGenericClass&lt;out T&gt; where T : BackgroundWorker
{
    T BackgroundWorker { get; }
}

Then you can use this interface like this

public class AnotherClass
{
   public IGenericClass&lt;BackgroundWorker&gt; Derived;

   public void DoSomething()
   {
      Derived = new DerivedOne();
   }
}

public class DerivedOne : IGenericClass&lt;BackgroundWorkerOne&gt;
{
    public BackgroundWorkerOne BackgroundWorker { get; }
}

huangapple
  • 本文由 发表于 2023年3月3日 18:09:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75625694.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定