代码之家  ›  专栏  ›  技术社区  ›  FallenAvatar

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

  •  0
  • FallenAvatar  · 技术社区  · 16 年前

    这是我的情况。我正在C#中使用WMI。谢天谢地,我发现 MgmtClassGen.exe

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

    我想把这些函数放在基类中,因为它们在所有类中都是相同的,除了3个变量。即 ClassName (比如说) MicrosoftDNS_Zone Namespace root\microsoftdns )和 ManagementScope 对象

    我现在所做的就是这样;将包含代码的2个函数移到基类中,并为上面列出的3个差异添加了3个参数。但这仍然需要在每个类中包含8个函数,这些函数只使用 命名空间 Scope

    1. 有没有办法重构这个 每个派生类中的“包装器”?
    2. 我可以声明静态吗 不知怎的从…那里得到了类名等 派生类?
    3. 反思在这里能起作用吗?

    基类:

    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 );
            }
        }
    }
    

    namespace WMI.MicrosoftDNS
    {
        public class AAAAType : WMI.Object
        {
            private static string CreatedWmiNamespace = "root\\microsoftdns";
            private static string CreatedClassName = "MicrosoftDNS_AAAAType";
            private static System.Management.ManagementScope statMgmtScope = null;
    
            // ...
    
            public static WMI.ManagementTypeCollection GetInstances()
            {
                return GetInstances( null, null, null );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( string condition )
            {
                return GetInstances( null, condition, null );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( System.String[] selectedProperties )
            {
                return GetInstances( null, null, selectedProperties );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( string condition, System.String[] selectedProperties )
            {
                return GetInstances( null, condition, selectedProperties );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, EnumerationOptions enumOptions )
            {
                return WMI.Object.GetInstances( CreatedClassName, CreatedWmiNamespace, statMgmtScope, mgmtScope, enumOptions, mo => new AAAAType( mo ) );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, string condition )
            {
                return GetInstances( mgmtScope, condition, null );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, System.String[] selectedProperties )
            {
                return GetInstances( mgmtScope, null, selectedProperties );
            }
    
            public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, string condition, System.String[] selectedProperties )
            {
                return WMI.Object.GetInstances( CreatedClassName, CreatedWmiNamespace, statMgmtScope, mgmtScope, condition, selectedProperties, mo => new AAAAType( mo ) );
            }
        }
    }
    
    3 回复  |  直到 16 年前
        1
  •  2
  •   LBushkin    16 年前

    下面是我的意思的一个例子:

    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; } }
    }
    
        2
  •  1
  •   tbreffni    16 年前

    optional arguments 方法的默认值,这在很多情况下消除了多个重载的需要。例如:

    public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10)

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

        3
  •  0
  •   user76035    16 年前

    也许是个小工厂?

    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{ ... });
         }
    }
    

    • 静电过多
    • 一个方法的6个参数,包括一个函数指针真的吗?
    • 在顶部使用两个有助于避免限定名
    • 获得代码的意图并不容易