C#通过< T>定义基类 [英] C# Define base class by <T>

查看:152
本文介绍了C#通过< T>定义基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种从泛型基类派生类的方法。说:

  sealed public class Final:Base< Something> {

}

public class Base< T> :T其中T:Anything {//< - 泛型不允许此

}

在C#中,这似乎是不可能的。



是否有任何其他解决方案可以实现与此类似的功能?

我发现这个 StackOverflow问题,但它似乎并没有解决问题,或者至少我不明白它应该如何。



编辑:



我希望得到的结果是能够做到这样的事情:

 任何[]任何东西; 
//将一些实例赋值给任何事

foreach(最终决定任何事情){
//用最后的
做一些事情}


解决方案


我想得到的结果是能够做这样的事情:

 任何东西[]什么; 
//将一些实例赋值给任何事

foreach(最终决定任何事情){
//用最后的
做一些事情}

您的 foreach 循环提示: class Anything:Final {...}



这显然是按照您的计划和命名继承层次结构。 (您的继承关系中不能有循环)。







  public class Base< T> :T where T:Anything {... 


让我详细说明这一点一点点。我会将你的例子进一步缩小到 class Base< T> :T



这是不可能的,理由很充分。想象一下:

  class Base< T> :T 
{
public override string Frobble()
{
Fiddle();
返回*+ base.Frobble()+*;





公共密封字符串Frobble(){...}
}

class B
{
}

class C
{
公共虚拟字符串Frobble(){...}
}

抽象类D
{
public abstract void Fiddle();
public virtual string Frobble(){...}
}

class E
{
public void Fiddle(){...}
public虚拟字符串Frobble(){...}
}

如果您遇到各种荒谬的情况 class Base< T> :T 被允许。




  • 基准< A> 将是荒谬的,因为 Frobble 不能在派生类中重写。

  • Base< B> 是荒谬的,因为您无法重写基类中不存在
    的方法。

  • Base< C> 不起作用,因为没有 Fiddle 方法来调用。
  • Base< D> 不起作用,因为您无法调用抽象方法。 b
  • 只有 Base< E> 才会有效。


编译器知道如何正确编译 Base< T> 并分析依赖它的代码? 是你不能从编译时不知道的类派生出来。 T 是一个参数,即一个变量,一个占位符。所以 class Base< T> :T 基本上是这样说的: Base< T> 从某些(未知)类继承而来。类继承是一种类型关系,它要求在编译时都知道所涉及的两种类型。 (实际上,这不是一个超精确的陈述,因为你可以继承一个泛型类型,比如 class SpecialList< T>:List< T> 。但至少,派生类必须知道基类中有哪些成员(方法,属性等)。)


I am trying to find a way to derive a class from a generic base class. Say:

sealed public class Final : Base<Something>{

}

public class Base<T> : T where T : Anything { //<- Generics do not allow this

}

In C# this does not seem to be possible.

Is there any other solution to achieve something similar to this?

I found this StackOverflow question, but it doesn't seem to solve the issue, or at least I do not understand how it should.

EDIT:

The result I'd like to get is to be able to do something like that:

Anything[] anything;
//Assign some Instances to anything 

foreach(Final final in anything){
     //do something with final
}

解决方案

The result I'd like to get is to be able to do something like that:

 Anything[] anything;
 //Assign some Instances to anything 

 foreach(Final final in anything){
     //do something with final
 }

Your foreach loop suggests this: class Anything : Final { … }.

This obviously turns around the inheritance hierarchy as you planned and named it. (You cannot have cycles in your inheritance relationships).


public class Base<T> : T where T : Anything { …

Let me elaborate on this part for a bit. I'll reduce your example even further to just class Base<T> : T.

This is not possible, for good reason. Imagine this:

class Base<T> : T
{
    public override string Frobble()
    {
        Fiddle();
        return "*" + base.Frobble() + "*";
    }
}

class A
{
    public sealed string Frobble() { … }
}

class B
{
}

class C
{
    public virtual string Frobble() { … }
}

abstract class D
{
    public abstract void Fiddle();
    public virtual string Frobble() { … }
}

class E
{
    public void Fiddle() { … }
    public virtual string Frobble() { … }
}

You get all kinds of absurd situations if class Base<T> : T were allowed.

  • Base<A> would be absurd because Frobble cannot be overridden in a derived class.
  • Base<B> would be absurd because you cannot override a method that doesn't exist in the base class.
  • Base<C> doesn't work because there is no Fiddle method to call.
  • Base<D> would not work because you cannot call an abstract method.
  • Only Base<E> would work.

How would the compiler ever know how to correctly compile Base<T> and analyse code that depends on it?

The point is that you cannot derive from a class that is not known at compile-time. T is a parameter, i.e. a variable, a placeholder. So class Base<T> : T is basically like saying, "Base<T> inherits from some (unknown) class". Class inheritance is a type relationship that requires both involved types to be known at compile-time. (Actually, that's not a super-precise statement because you can inherit from a generic type such as class SpecialList<T> : List<T>. But at the very least, the derived class has to know what members (methods, properties, etc.) are available in the base class.)

这篇关于C#通过&lt; T&gt;定义基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆