在我的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());
}
}
答案 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