希望在C#中使用静态抽象函数。有什么解决办法吗?

希望在C#中使用静态抽象函数。有什么解决办法吗?,c#,oop,C#,Oop,这是我的情况。我正在C#中使用WMI。谢天谢地,我发现它生成了我现在需要的所有类 但是,我一直在浏览自动生成的类,并将公共代码拆分为实用程序类或基类。到目前为止,很好,清理了很多代码。但我遇到了一个障碍。每个类都有几个(大约8个)静态函数,称为GetInstances。基本上有两个重载,另一个函数只提供默认参数 我想把这些函数放在基类中,因为它们在所有类中都是相同的,除了3个变量。即,对象的ClassName(如“MicrosoftDNS\u Zone”),对象的命名空间(如“root\Micr

这是我的情况。我正在C#中使用WMI。谢天谢地,我发现它生成了我现在需要的所有类

但是,我一直在浏览自动生成的类,并将公共代码拆分为实用程序类或基类。到目前为止,很好,清理了很多代码。但我遇到了一个障碍。每个类都有几个(大约8个)静态函数,称为
GetInstances
。基本上有两个重载,另一个函数只提供默认参数

我想把这些函数放在基类中,因为它们在所有类中都是相同的,除了3个变量。即,对象的
ClassName
(如“
MicrosoftDNS\u Zone
”),对象的
命名空间
(如“
root\MicrosoftDNS
”),以及
ManagementScope
对象

我现在所做的就是这样;将包含代码的2个函数移到基类中,并针对上面列出的3个差异添加了3个参数。但这仍然需要每个类中有8个函数,它们只调用基类,并填充
类名
命名空间
、和
范围
参数

  • 有没有办法重构这个 代码,这样我就不需要这个方法了 每个派生类中的“包装器”
  • 我可以声明静态吗 基类中的方法和 以某种方式从中获取类名等 派生类
  • 反思在这里会起作用吗
  • 基类:

    namespace WMI
    {
        public abstract class Object : System.ComponentModel.Component
        {
            // ...
            protected static WMI.ManagementTypeCollection GetInstances( string className, string namespaceName, ManagementScope statMgmtScope, ManagementScope mgmtScope, EnumerationOptions enumOptions, Func<ManagementObject,WMI.Object> del )
            {
                if( (mgmtScope == null) )
                {
                    if( (statMgmtScope == null) )
                    {
                        mgmtScope = new System.Management.ManagementScope();
                        mgmtScope.Path.NamespacePath = namespaceName;
                    }
                    else
                    {
                        mgmtScope = statMgmtScope;
                    }
                }
                System.Management.ManagementPath pathObj = new System.Management.ManagementPath();
                pathObj.ClassName = className;
                pathObj.NamespacePath = namespaceName;
                System.Management.ManagementClass clsObject = new System.Management.ManagementClass( mgmtScope, pathObj, null );
                if( (enumOptions == null) )
                {
                    enumOptions = new System.Management.EnumerationOptions();
                    enumOptions.EnsureLocatable = true;
                }
                return new WMI.ManagementTypeCollection( clsObject.GetInstances( enumOptions ), del );
            }
    
            protected static WMI.ManagementTypeCollection GetInstances( string className, string namespaceName, ManagementScope statMgmtScope, ManagementScope mgmtScope, string condition, String[] selectedProperties, Func<ManagementObject, WMI.Object> del )
            {
                if( (mgmtScope == null) )
                {
                    if( (statMgmtScope == null) )
                    {
                        mgmtScope = new System.Management.ManagementScope();
                        mgmtScope.Path.NamespacePath = namespaceName;
                    }
                    else
                    {
                        mgmtScope = statMgmtScope;
                    }
                }
                System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher( mgmtScope, new SelectQuery( className, condition, selectedProperties ) );
                System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions();
                enumOptions.EnsureLocatable = true;
                ObjectSearcher.Options = enumOptions;
                return new WMI.ManagementTypeCollection( ObjectSearcher.Get(), del );
            }
        }
    }
    

    这可能不是您的选择,但C#4.0支持方法的默认值,这在很多情况下消除了需要有多个重载。例如:

    public void ExampleMethod(需要int,字符串optionalstr=“默认字符串”,
    int optionalint=10)


    您可以使用
    ExampleMethod(1)
    ExampleMethod(1,'Test',9)

    调用上述方法。这可能不是您的选项,但C#4.0支持方法的默认值,这在许多情况下消除了使用多个重载的需要。例如:

    public void ExampleMethod(需要int,字符串optionalstr=“默认字符串”,
    int optionalint=10)


    您可以使用
    ExampleMethod(1)
    ExampleMethod(1,'Test',9)
    调用上述方法,为什么不将这八个常用函数作为实例方法移动到一个单独的类中,并使用三个随类而异的参数初始化实例呢。然后,可以在每个派生类型上聚合并公开该助手类的实例。因为静态方法不能使用任何实例数据,所以没有理由复制它们

    这里有一个例子来说明我的意思:

    public class WMIInstance
    {
        private readonly string CreatedWmiNamespace = "root\\microsoftdns";
        private readonly string CreatedClassName = "MicrosoftDNS_AAAAType";
        private readonly System.Management.ManagementScope statMgmtScope = null;
    
        public WMIInstance( string namespace, string className, ManagementScope scope )
        { /*... initialize private members here... */
    
        public WMI.ManagementTypeCollection GetInstances( System.String[] selectedProperties )
        { return WMI.Object.GetInstances( ... ); }
    
        /* other overloads ... */
    }
    
    public class AAAAType : WMI.Object
    {
        private static string CreatedWmiNamespace = "root\\microsoftdns";
        private static string CreatedClassName = "MicrosoftDNS_AAAAType";
        private static System.Management.ManagementScope statMgmtScope = null;
    
        private static readonly WMIInstances _instances = new WMIInstance( CreatedWmiNamespace, CreatedClassName, statMgmgtScope );
    
        public static WMIInstances Getter { get { return _instances; } }
    }
    

    为什么不将这八个常用函数作为实例方法移动到一个单独的类中,并使用三个因类而异的参数初始化实例呢。然后,可以在每个派生类型上聚合并公开该助手类的实例。因为静态方法不能使用任何实例数据,所以没有理由复制它们

    这里有一个例子来说明我的意思:

    public class WMIInstance
    {
        private readonly string CreatedWmiNamespace = "root\\microsoftdns";
        private readonly string CreatedClassName = "MicrosoftDNS_AAAAType";
        private readonly System.Management.ManagementScope statMgmtScope = null;
    
        public WMIInstance( string namespace, string className, ManagementScope scope )
        { /*... initialize private members here... */
    
        public WMI.ManagementTypeCollection GetInstances( System.String[] selectedProperties )
        { return WMI.Object.GetInstances( ... ); }
    
        /* other overloads ... */
    }
    
    public class AAAAType : WMI.Object
    {
        private static string CreatedWmiNamespace = "root\\microsoftdns";
        private static string CreatedClassName = "MicrosoftDNS_AAAAType";
        private static System.Management.ManagementScope statMgmtScope = null;
    
        private static readonly WMIInstances _instances = new WMIInstance( CreatedWmiNamespace, CreatedClassName, statMgmgtScope );
    
        public static WMIInstances Getter { get { return _instances; } }
    }
    
    也许是一个小工厂

    class Config { string ClassName; string Namespace; ManagementScope Scope; }
    
    static class Factory {
         public static readonly Dictionary<Type, Config> Configs = new ...;
    
         static GetInstances(Type requestedType, ...) {
             var config = Configs[requestedType];
             // work with it...
         }
    }
    
    class AAAAType {
         static AAAAType{
              Factory.Configs.Add(typeof(AAAAType), new Config{ ... });
         }
    }
    
    class-Config{string-ClassName;string-Namespace;ManagementScope;}
    静态类工厂{
    公共静态只读字典Configs=new。。。;
    静态GetInstances(类型requestedType,…){
    var config=Configs[requestedType];
    //用它工作。。。
    }
    }
    AAAA类{
    静态AAAAType{
    Add(typeof(AAAAType),新配置{…});
    }
    }
    
    这可能不是完美的代码,但我不想偏离你最初的建议太远。此外,我不太喜欢它,我建议重新设计您的想法,因为:

    • 太多静电
    • 6个参数到一个方法,包括一个函数指针真的吗
    • 系统字符串?可能还有其他字符串类型,所以您可以将其限定为那么强
    • 在顶部使用两个名称将有助于避免使用限定名称
    • 获得代码的意图并不容易
      • 也许是个小工厂

        class Config { string ClassName; string Namespace; ManagementScope Scope; }
        
        static class Factory {
             public static readonly Dictionary<Type, Config> Configs = new ...;
        
             static GetInstances(Type requestedType, ...) {
                 var config = Configs[requestedType];
                 // work with it...
             }
        }
        
        class AAAAType {
             static AAAAType{
                  Factory.Configs.Add(typeof(AAAAType), new Config{ ... });
             }
        }
        
        class-Config{string-ClassName;string-Namespace;ManagementScope;}
        静态类工厂{
        公共静态只读字典Configs=new。。。;
        静态GetInstances(类型requestedType,…){
        var config=Configs[requestedType];
        //用它工作。。。
        }
        }
        AAAA类{
        静态AAAAType{
        Add(typeof(AAAAType),新配置{…});
        }
        }
        
        这可能不是完美的代码,但我不想偏离你最初的建议太远。此外,我不太喜欢它,我建议重新设计您的想法,因为:

        • 太多静电
        • 6个参数到一个方法,包括一个函数指针真的吗
        • 系统字符串?可能还有其他字符串类型,所以您可以将其限定为那么强
        • 在顶部使用两个名称将有助于避免使用限定名称
        • 获得代码的意图并不容易

        对于任何想知道的人来说,Func是一种将集合项作为WMI.Object而不是System.Management.ManagementObject返回以在我的其余代码中使用的黑客。为什么不执行Collection.Cast().ToList();因为System.Management.ManagementObjects不是WMI.Objects:-p对于任何想知道的人来说,Func是一个黑客,它将集合项作为WMI.Object而不是System.Management.ManagementObject返回,以便在我的其余代码中使用。为什么不执行Collection.Cast().ToList();因为System.Management.ManagementObjects不是WMI.Objects:-PYes,我正在使用C#4.0,并计划这样做。然而,这使得我需要在接近75个文件中复制/操作2个函数(实际上有2个不同的重载)。如果我需要使用任何其他WMI类,还需要更多。。。我总是讨厌有重复的代码