如何在静态构造函数中获取类类型信息. [英] How to get the class type info in static constructors.

查看:66
本文介绍了如何在静态构造函数中获取类类型信息.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

我正在寻找一种更优雅的方法来在静态构造函数中检索类型信息.

这是问题的一个示例:

Hi Folks,

I''m looking for a more elegant way to retrieve the type information in a static constructor.

Here is a sample of the problem:

public class Base
{
    private static Type _typeInfo;
    public static string TypeName;
    static Base()
    {
        //Type info goes here. Not Base class type info but from any derived class.
        _typeInfo = ????; 
        TypeName = _typeInfo.Name;
    }
}

public class Derived : Base
{
}

//I want those asserts to work.
Assert.AreEqual("Base", Base.TypeName);
Assert.AreEqual("Derived", Derived.TypeName);



我不需要(甚至不想)这些类被实例化.我只需要它们的静态属性和方法.

有一个使用泛型的解决方案:



I don''t need (or even want) those classes to be instanciated. I just need their static properties and methods.

There is a solution using generics:

public class Base<TSource> where TSource : Base<TSource>
{
    private static Type _typeInfo;
    public static string TypeName;
    static Base()
    {
        _typeInfo = typeof(TSource);
        TypeName = _typeInfo.Name;
    }

    public static string CommonInfo = "PresentInAllClasses";
}

public class Derived1<TSource> : Base<TSource> where TSource : Derived1<TSource>
{
    public static string DerivedInfo = "OnlyOnDerivedClasses";
}

public class Base : Base<Base> { }

public class Derived1 : Derived1<Derived1> { }

public class Derived2 : Derived1<Derived2>
{
    public static string FinalInfo = "OnlyInFinalClass";
}

//Those asserts works fine.
Assert.AreEqual("Base", Base.TypeName);
Assert.AreEqual("Derived1", Derived1.TypeName);
Assert.AreEqual("Derived2", Derived2.TypeName);
Assert.AreEqual("PresentInAllClasses", Base.CommonInfo);
Assert.AreEqual("PresentInAllClasses", Derived1.CommonInfo);
Assert.AreEqual("PresentInAllClasses", Derived2.CommonInfo);
Assert.AreEqual("OnlyOnDerivedClasses", Derived1.DerivedInfo);
Assert.AreEqual("OnlyOnDerivedClasses", Derived2.DerievedInfo);
Assert.AreEqual("OnlyInFinalClass", Derived2.FinalInfo);



但我认为它不是非常优雅的解决方案"原因:
1-我必须在声明中写两次目标类的名称. (丑)
2-我必须传播要扩展的任何子类的泛型声明. (非常难看)
3-我必须将目标类声明为其自身的泛型. (非常非常难看)

有什么想法吗?

谢谢
Andre Vianna



But I don’t see it as very elegant solution ''cause:
1 - I have to write the name of the target classes twice in it''s declaration. (ugly)
2 - I have to propagate the generic declaration for any subclass I want to extend. (very ugly)
3 - I have to declare the target class as a generic of itself. (Very, very ugly)

Any ideas?

Thanks
Andre Vianna

推荐答案

您要问的内容没有任何意义.静态成员处理类型而不是对象,并且您已经发现多态性仅适用于对象实例.

请考虑以下情况:Base.TypeName每个AppDomain只能容纳一个字符串值.如果您拥有基类和派生类,它将持有什么价值?它不能更改值,具体取决于它是通过Base.TypeName还是Derived.TypeName访问的.

尼克
What you''re asking doesn''t make sense. Static members deal with types not objects and as you''ve found out polymorphism only works with instances of objects.

Consider this: Base.TypeName can only hold one string value per AppDomain. What value would it hold if you had the Base class and a derived class? It can''t change value depending on if it was accessed through Base.TypeName or Derived.TypeName.

Nick



您试图实现的目标似乎不可能(或至少没有用).
类的静态构造函数在程序生命周期内最多只能调用一次,并且不会被继承.因此,即使您设置了正确的类型,也只会为基类设置它,而您将不得不在派生类中再次设置它.
也许您可以使用typeof().
例如:

Hi,
It seems like its impossible what you are trying to achieve(or at least useless).
Static constructor of a class is called at most one time during program life and it is not inherited. So even if you set correct type it will be set only for the Base class and you will have to set it again in derived classes.
Maybe you could make use of typeof().
for e.g.:

class Utils{
public static string GiveMeName(Type t){
    //add whatever info more you need here}
}

Utils.GiveMeName(typeof(Base));



嗯..它不是您想要的那么漂亮,但是可以完成工作:P
..或您可以使用泛型
..或在所有类的静态构造函数中重写相同的代码



Well.. its not so pretty as you might want but it does the job :P
..or you could use generics
..or rewrite same code in static constructors for all classes


我不知道什么时候有人会需要您尝试实现的功能,但这还不重要:)

由于Base的静态构造函数不会像非静态构造函数那样被称为链接调用图,而是在首次使用Base实例创建时或当访问静态成员时,您不能继承为静态方法,以获取派生类型.

如果您确实需要此信息,则可以在每个类上使用静态属性来解决它:

I can not figure out when anyone would ever need what you''re trying to achieve, but that''s beside the point :)

As the static constructor of Base will not be called as a chained call graph, such in the case of the non static constructor, but rather on first use of a instance of Base is created or when a static member is accessed you can''t get to the derived type as static methods are inherited.

If you really do need this information I''d solve it with static properties on each class:

public class Base
{
    public static string TypeName
    {
        get { return typeof(Base).Name; }
    }
}

public class Derived : Base
{
    public static string TypeName
    {
        get { return typeof(Derived).Name; }
    }
}



至少以这种方式,丑陋(即重复代码)将被包含并隐藏在类中,而不是强迫类的用户指定冗余类型参数以让泛型确定类型.

希望这会有所帮助.



At least this way the uglyness (i.e. repeating code) will be contained and hidden away in the classes rather than forcing the user of your classes to specify redundant type arguments to let generics figure the type out.

Hope this helps.


这篇关于如何在静态构造函数中获取类类型信息.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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