C# 在c中访问泛型类上的静态方法#

C# 在c中访问泛型类上的静态方法#,c#,generics,inheritance,static,methods,C#,Generics,Inheritance,Static,Methods,我在代码中遇到了以下情况,我怀疑这可能有点狡猾: 我有一门课: abstract class DataAccessBase<T> : IDataAccess where T : AnotherAbstractClass 现在,从DataAccessBase派生的类型本身不是泛型的,它们为T指定了一个类型: class PoLcZoneData : DataAccessBase<PoLcZone> // PoLcZone is derived from AnotherAb

我在代码中遇到了以下情况,我怀疑这可能有点狡猾:

我有一门课:

abstract class DataAccessBase<T> : IDataAccess where T : AnotherAbstractClass
现在,从
DataAccessBase
派生的类型本身不是泛型的,它们为T指定了一个类型:

class PoLcZoneData : DataAccessBase<PoLcZone> // PoLcZone is derived from AnotherAbstractClass
class PoLcZoneData:DataAccessBase//PoLcZone派生自另一个抽象类
到目前为止,我不确定这是否会限制泛型的良好使用,但我真正关心的是如何首先访问静态
CreateInstance()
方法:

我现在做这件事的方法是简单地传递任何类型T,其中T:
另一个抽象类
。特别是我正在传递另一个抽象类本身。这允许进行编译,但在我看来,将任何类型传递给泛型类只是为了获得静态数据有点狡猾

我实际上简化了这种情况,因为
DataAccessBase
是继承链中的较低级别,但是静态工厂方法存在于中间层,其中类
PoLcZoneData
是唯一非泛型级别上派生最多的类


人们对这种安排有什么想法?

我认为这种设计没有任何问题,特别是如果您使用模板参数来指定实现细节。我的建议是让工厂功能不是静态的,而是独立的。这对我来说是最明确的方式

如果您想以某种方式封装它,那么我建议使用名称空间或命名约定

另一种解决方案是通过定义一种DataAccessBase类型来隐藏您当前正在做的事情,可能如下所示:

typedef DataAccessBase<AnotherAbstractClass> DataAccessBaseFactory;
typedef-DataAccessBase-DataAccessBase-factory;

这是我最不推荐的解决方案,但如果您绝对希望Create函数是静态的,它会将其保留为静态的。

您可以拥有一个同名的非泛型类。。。也许是这样的:

abstract class DataAccessBase<T> : IDataAccess where T : AnotherAbstractClass
{
    ...
}
static class DataAccessBase
{
    public static IDataAccess CreateInstance(TypeToCreateEnum) {...}
}
抽象类DataAccessBase:IDataAccess其中T:AnotherAbstractClass
{
...
}
静态类DataAccessBase
{
公共静态IDataAccess CreateInstance(TypeToCreateEnum){…}
}

现在您可以使用
DataAccessBase.CreateInstance
,而无需任何冗余
T
。通常,您可以从
DataAccessBase
调用
DataAccessBase
上的
internal
方法-尽管我怀疑在您的场景中,您可能还需要一些反思/
MakeGenericType

我刚才遇到了类似的问题(“如何重载静态方法”)我沉思着解决了这个问题

我的情况如下:

1)
公共抽象类AuditObject:ActiveRecordBase
(是的,我正在使用ActiveRecord)和

2)
公共类员工:AuditObject

在这两种方法中,我都定义了一些静态方法,例如

public static DataTable GetLookupTable(String where, Int32 topRows)
{
    return doExtremelyCleverStuffToFetchData(where, topRows);
}
(在#2中,您需要
public**new**static
,否则会收到编译器警告)

正如代码所示,当我调用例如

DataTable myList = AuditObject<T>.GetLookupTable("inactive = 0", 100);
下面是“override”方法的调用方式:

public static Object invokeStaticMethod<T>(String MethodName, Object[] Args)
{
    return typeof(T).InvokeMember(MethodName,
        BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
        null, null, Args);
}
publicstaticobjectinvokeStaticMethod(stringmethodname,Object[]Args)
{
返回typeof(T).InvokeMember(MethodName,
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null,null,Args);
}
瞧!当我调用
DataTable myList=AuditObject.GetLookupTable时(“inactive=0”,100)
T是Employee,我从Employee类中定义的静态方法获得结果

希望这有帮助


迪米特里斯

对不起,是C。忘了将其添加到标题中。好吧,在这种情况下,我想唯一的选择是将工厂函数封装在单独的类中,而不是命名空间中
public static DataTable GetLookupTable(String where, Int32 topRows)
{
    DataTable tbl = null;

    Boolean hasOverride = hasMethodOverride("GetLookupTable");

    if (hasOverride)
    {
        tbl = invokeStaticMethod<T>(
            "GetLookupTable", new Object[2] { where, topRows })
            as DataTable;
    }
    else
    {
        tbl = doExtremelyCleverStuffToFetchData(where, topRows);
    }

    return tbl;
}
private static Boolean hasMethodOverride(String methodName)
{
    var methodQuery =
        from method in typeof(T).GetMethods(
            BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod)
        where method.Name == methodName
        select method;

    return methodQuery.Count() > 0;
}
public static Object invokeStaticMethod<T>(String MethodName, Object[] Args)
{
    return typeof(T).InvokeMember(MethodName,
        BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
        null, null, Args);
}