请参阅班级

时间:2015-05-11 02:31:51

标签: c# types self

在我的C#类中,我想引用类本身的类型,是否可能?

我的示例代码:

中的

private static List<CRcpParmPropEle<CParam1, string>> ParmPropList;

我不想使用&#34; CParam1&#34;,我希望使用一些通用方式(例如&#34;这个&#34;)来引用自己。因为我有很多像CParam1这样的课程,所以每个人都需要这样参考。

class CParam1
{

    private double m_Prop1;

    private static List<CRcpParmPropEle<CParam1, string>> ParmPropList;

    public CParam1()
    {

    }

    ////-> I wish to replace Cparam1 to something like this
    public static List<CRcpParmPropEle<CParam1, string>> getParmPropList()
    {
        if (ParmPropList == null)
        {                
            ParmPropList.Add(new CRcpParmPropEle<CParam1, string>("Prop1", "BA", 0, false));
            //-> I wish to replace Cparam1 to something like this
        }
        return ParmPropList;
    }

    public string Prop1
    {
        get
        {
                return m_Prop1.ToString();
        }
        set
        {
            m_Prop1 = -1;
            double dW1;
            if (double.TryParse(value, out dW1))
            {
                    m_Prop1 = dW1;
            }
        }
    }

public class CRcpParmPropEle<T,TProp>
{
    public Func<T, TProp> getter;
    public Action<T, TProp> setter;

    public string PropName { get; set; }
    public string ColPos { get; set; }
    public int ColNum { get; set; }
    public int RowNum { get; set; }

    public bool ReadOnly { get; set; }

    public CRcpParmPropEle(string strPropName, string strColPos, int nRowNum, bool bReadOnly)
    {
        PropName = strPropName;
        ColPos = strColPos;
        RowNum = nRowNum;

        ReadOnly = bReadOnly;

        var prop = typeof(T).GetProperty(PropName);    //typeof(rcpObj).GetProperty(propName);
        getter = (Func<T,TProp>)Delegate.CreateDelegate(typeof(Func<T,TProp>), prop.GetGetMethod());
        setter = (Action<T,TProp>)Delegate.CreateDelegate(typeof(Action<T,TProp>), prop.GetSetMethod());            
    }
}

2 个答案:

答案 0 :(得分:1)

一般来说,没有。没有办法做到这一点。因为在通常使用它的上下文中,无论如何都要编写特定于该类型的代码,并且因为我们习惯于必须为静态成员指定类型名称,所以这似乎不是很困难。 / p>

但是,有两种方法可以在你的场景中起作用,都涉及泛型。

第一种方法是将新对象的构造委托给通用辅助方法:

public static List<CRcpParmPropEle<CParam1, string>> getParmPropList()
{
    if (ParmPropList == null)
    {
        AddToList(ParmPropList, "Prop1", "BA", 0, false);
    }
    return ParmPropList;
}

private static void AddToList<T>(List<CRcpParmPropEle<T, string>> list, string s1, string s2, int i, bool f)
{
    list.Add(new CRcpParmPropEle<T, string>(s1, s2, i, f));
}

通过这种方式,实际类型是从传入的List<T>对象的类型推断出来的,因此不需要重新调整。当然,您不会指定某处类型。它只是不会在这个特定的呼叫站点结束。

另一种选择是使用静态助手类来实现CParam1类的静态功能:

static class ParmPropClass<T>
{
    private static List<CRcpParmPropEle<T, string>> ParmPropList;

    public static List<CRcpParmPropEle<T, string>> getParmPropList()
    {
        if (ParmPropList == null)
        {
            ParmPropList.Add(new CRcpParmPropEle<T, string>("Prop1", "BA", 0, false));
        }
        return ParmPropList;
    }
}

然后,当您使用静态成员时,您必须将类型名称指定为ParmPropClass<CParam1>(或者其他任何内容,具体取决于您命名帮助程序类的内容)。同样,您不会在某处指定类型名称,但调用站点不需要。

事实上,如果你在许多地方做这种完全的模式,那么通用助手类型可能是更好的方法,因为那时你不必复制/一直粘贴代码(未能修复复制到的所有位置的错误的配方)。

答案 1 :(得分:1)

这里没有直截了当或易于实施的答案。我会给你三个选择,但我不认为这些选项比改变所有类更容易。如果我必须这样做,我会使用依赖注入器。从长远来看,你会变得更好,下次你能够更轻松地处理这些事情。如果我必须快速和绝望地做,我会使用反射。

选项1 - 反思

您可以使用反射在运行时组装List。 请查看此帖子,了解在运行时使用反射创建列表的示例。 Generic list by using reflection

这将使您的代码非常难以维护,您将不得不使用反射来管理列表。您可能会在运行时错误和调试困难中添加更多麻烦,而不仅仅是在任何地方更改它

选项2 - 公共基类

如果可以从公共基类CPARAMBASE实现所有CPARAM1类型对象,则可以使用公共基类定义列表。

private static List<CRcpParmPropEle<CParamBase, string>> ParmPropList;

选项3 - 依赖注入

这不是你可以在SO答案中介绍的内容,而是看看依赖注入。

您可以在所有CPARAM类型类之间创建一个接口,然后根据注入的类型注入具体类型。

   [Inject]
   private static List<CRcpParmPropEle<ICParam, string>> ParmPropList;

在您的依赖项注入中,您可以定义ICParam实例。

this.Bind<List<CRcpParmPropEle<ICParam, string>>>()
    .To<List<CRcpParmPropEle<CParam1, string>>>()
    .WhenInjectedInto(typeof(CParam1));

查找Ninject,然后查看Contextual Binding和http://www.ninject.org/wiki.html