使用在抽象类的子类上工作的泛型类中的抽象类的静态属性 [英] using static property of an abstract class inside a generic class that works on subclasses of the abstract class

查看:235
本文介绍了使用在抽象类的子类上工作的泛型类中的抽象类的静态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 抽象类a 
{
public static字符串x;
}



class b< c>其中c:a
{
public void f()
{
c.x = 10;
}
}

这段代码不能编译。我在语句c.x = 10处得到一个错误; 。这个问题使得它看起来好像条件其中c:a 根本没有任何作用。请解释一下为什么这是一个错误? x是否被所有的孩子分享为静态成员?有没有办法来规避这个问题?

我想要实现的是这样的:我有一个a的子类,所有的对象共享一个公共属性,这个属性必须通过泛型类b中的f()来设置。如果我用a.x = 10来替换有问题的语句是否可以?如果不是,ax与cx(或hx的不同之处在哪里,h是a的子类)?解决方案

静态成员不是尽管通过派生类型访问静态成员可能会造成混淆。例如,在下面的代码中:

  class P 
{
public static string X;
}

class Q:P {}

class R:P {}

您可以通过 PX PX > QX 或 RX 但它仍然是相同的字段:

  PX =你好; 
Q.X =世界;
Console.WriteLine(R.X); //打印World

正如您发现的那样,您不能使用泛型类型参数。但是访问 X ,尽管type参数并没有太大的意义,因为你改变的只是 PX ,它您直接编写而不使用泛型类型参数。




我不确定您想要实现的目标。如果您有一个抽象类 A ,并且希望从 A 派生的所有类型的实例具有某个属性,那么您可以定义这个:

 抽象类A 
{
公共抽象字符串X
{
得到;



class A1:A
{
public override string X
{
get {returnA1 ; }



class A2:A
{
public override string X
{
get {returnA2 ; }
}
}






如果要将一些信息与类型(不是实例)关联起来,可以使用泛型类定义一个静态字段,该字段使用类型参数化:

  class Info< T> 
{
public static string X;
}

信息< A1> .X =你好;
信息< A2> .X =世界;

Console.WriteLine(Info< A1> .X); //打印Hello
Console.WriteLine(Info< A2> .X); //打印世界






这个怎么样?

 抽象类Job 
{
公共抽象字符串ExePath
{
get ;
}

public void Execute(string [] args)
{
Console.WriteLine(Executing {0},this.ExePath);
}
}

抽象类Job< T>其中T:Job< T>
{
public override string ExePath
{
get {return JobInfo< T> .ExePath; }
}
}

class ConcreteJob1:Job< ConcreteJob1> {}

class ConcreteJob2:Job< ConcreteJob1> {}

静态类JobInfo< T>其中T:Job< T>
{
public static string ExePath;


static class JobInfoInitializer
{
public static void InitializeExePaths()
{
JobInfo< ConcreteJob1> .ExePath =calc。可执行程序;
JobInfo< ConcreteJob2> .ExePath =notepad.exe;






这与您在评论中描述的过程密切相关。它应该可以工作,但我不会设计一个可配置的Job模型。


I have a question regarding the following code:

abstract class a
{
    public static string x;
}



class b<c> where c : a
{
    public void f()
    {
        c.x=10;
    }
}

This code does not compile. I get an error at the statement c.x=10; . The problem makes it look as if the condition where c:a does not have any effect at all.Can someone please explain why this is an error? Is it not true that x is shared as a static member by all children of a? And is there a way to circumvent this problem?

What I am trying to achieve is this : i have a subclass of a, all of whose objects share a common property and this property has to be set through f() in the generic class b. Is it alright if i replace the statement in question with a.x=10? If not, how is a.x different from c.x (or h.x where h is the subclass of a)?

解决方案

Static members are not inherited, although it's confusingly possible to access a static member through a derived type. For example, in the following code

class P
{
    public static string X;
}

class Q : P { }

class R : P { }

you can access P.X through P.X or Q.X or R.X but it's still the same field:

P.X = "Hello";
Q.X = "World";
Console.WriteLine(R.X);  // prints "World"

As you've discovered, you can't do this with generic type parameters. But accessing X though the type parameter doesn't really make a lot of sense, because all you change is P.X which you write directly without the generic type parameter.


I'm not really sure what you're trying to achieve. If you have an abstract class A and want all instances of types that derive from A to have a certain property, you can define this:

abstract class A
{
    public abstract string X
    {
        get;
    }
}

class A1 : A
{
    public override string X
    {
        get { return "A1"; }
    }
}

class A2 : A
{
    public override string X
    {
        get { return "A2"; }
    }
}


If you want to associate a bit of information with a type (not instance), you can define a static field that is parameterized with a type using a generic class:

class Info<T>
{
    public static string X;
}

Info<A1>.X = "Hello";
Info<A2>.X = "World";

Console.WriteLine(Info<A1>.X);  // prints "Hello"
Console.WriteLine(Info<A2>.X);  // prints "World"


What about this?

abstract class Job
{
    public abstract string ExePath
    {
        get;
    }

    public void Execute(string[] args)
    {
        Console.WriteLine("Executing {0}", this.ExePath);
    }
}

abstract class Job<T> where T : Job<T>
{
    public override string ExePath
    {
        get { return JobInfo<T>.ExePath; }
    }
}

class ConcreteJob1 : Job<ConcreteJob1> { }

class ConcreteJob2 : Job<ConcreteJob1> { }

static class JobInfo<T> where T : Job<T>
{
    public static string ExePath;
}

static class JobInfoInitializer
{
    public static void InitializeExePaths()
    {
        JobInfo<ConcreteJob1>.ExePath = "calc.exe";
        JobInfo<ConcreteJob2>.ExePath = "notepad.exe";
    }
}

This matches closely the process you describe in your comment. It should work, although it's not how I would design a configurable Job model.

这篇关于使用在抽象类的子类上工作的泛型类中的抽象类的静态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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