给定一个通用抽象类型的类实例化

时间:2013-03-26 12:32:39

标签: c# generics

使用此模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
    #region Abstracts definitions
    abstract class AnAbstract
    {
        public string Name { get { return this.GetType().Name; } }
        public bool IsNumeric { get { return this is ANumericAbstract; } }
        public /*abstract*/ string Description = default(string);
    }
    abstract class ANumericAbstract : AnAbstract
    {
        public /*abstract*/ double Min = double.MinValue;
        public /*abstract*/ double Max = double.MaxValue;
    }
    abstract class ANonNumericAbstract : AnAbstract
    {
        public List<Object> objects = new List<Object>();
    }
    #endregion Abstracts definitions
    #region Concrete definitions
    class NumericImpl : ANumericAbstract
    {
        new public const string Description = "A numeric implementation";
        new public const double Min = 0;
        new public const double Max = 1000;
        public NumericImpl()
        {
        }
    }
    abstract class AnotherImpl : ANonNumericAbstract
    {
        public AnotherImpl()
        {
            objects.Add("one");
            objects.Add("two");
            objects.Add("three");
        }
    }
    class SideA : AnotherImpl
    {
        new public const string Description = "Disc side A";
    }
    class SideB : AnotherImpl
    {
        new public const string Description = "Disc side B";
    }
    #endregion Concrete definitions
    partial class Parameter
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsNumeric { get; private set; }
        public double Min { get; private set; }
        public double Max { get; private set; }
        public List<Object> Values { get; private set; }
        private Parameter()
        {
            Values = new List<Object>();
        }
    }
}

有了这个,我假装定义了一个类的层次结构,我可以为它提供一些抽象属性(NameDescriptionIsNumeric),并且在层次结构的末尾应该有是一些强制定义这些属性的类;在ANumericAbstract的情况下,他们应该具有其他特定属性,例如MinMax

现在问题就出现了。

我正在努力创建Parameter的实例,这些实例采用通用AnAbstract并从中读取一些值以填充Parameter属性,àla

Parameter<ANumericAbstract> ParamNum = new Parameter<NumericImpl>();

其中Parameter构造函数将接受传递的类型并“填充空白”。换句话说,我正在尝试这样的事情:

using System;
namespace ConsoleApplication1 {
    partial class Parameter 
    {
        public static Parameter NewParameter<T>() where T : AnAbstract
        {
            Parameter Parameter = new Parameter();

            // THESE DON'T WORK:
            this.Name = T.Name;
            this.Description = T.Description;
            this.IsNumeric = T.IsNumeric;
            if (this.IsNumeric) 
            {
               this.Min = (T as ANumericAbstract).Min;
               this.Max = (T as ANumericAbstract).Max; 
            }
            else 
            {
              foreach(Object val in (T as ANonNumericAbstract).Values)
              {
                this.Values.Add(val);
              }
            }

            return Parameter;
        }
    }

    class Program
    {
        private AnAbstract Number = new NumericImpl();
        static void Main(string[] args)
        {
        }

        // THESE DON'T WORK:
        private static Parameter<ANumericAbstract> ParameterNum = 
                       Parameter.NewParameter<NumericImpl>();
        private static Parameter<ANonNumericAbstract> ParameterA = 
                       Parameter.NewParameter<SideA>();
        private static Parameter<ANonNumericAbstract> ParameterB = 
                       Parameter.NewParameter<SideB>();
    }
}

显然语法无效,但我不确定我是否朝着正确的方向前进。是否有一些我没有正确使用的泛型语法?我是否应该完成它并使用Get ters和Set ters àla Java? :-)此时,只需执行

Parameter par = new Parameter { Name = NumericImpl.Name, /* ... */ };

似乎更明智......

1 个答案:

答案 0 :(得分:1)

首先,您不应在您的媒体资源上使用New关键字。 考虑virtual关键字:

abstract class AnAbstract
{
    public virtual string Name { get { return this.GetType().Name; } }
    public virtual string Description { get { return String.Empty; } }
}
abstract class ANumericAbstract : AnAbstract
{
    public virtual double Min = double.MinValue;
}

class NumericImpl : ANumericAbstract
{
    public override string Description { get { return "A numeric implementation"; } } 
    public override double Min { get { return 0; } }
}

1)您可以在Parameter构造函数中放置您键入的实例,并使用Parameter实例。

partial class Parameter 
{ 
    public Parameter(AnAbstract inputObject) 
    { 
        this.Name = inputObject.Name; 
        // etc
    } 
}

private static Parameter ParameterNum = new Parameter(new NumericImpl());

2)第二种方法是使用反射来创建具有初始参数的对象实例。

    partial class Parameter<T> where T : AnAbstract
    {
        public static Parameter<T> NewParameter<T>() where T : AnAbstract
        {
            Parameter<T> parameter = new Parameter<T>();
            AnAbstract instance = (AnAbstract)Activator.CreateInstance(typeof(T));

            parameter.Name = instance.Name;
            // etc
            return parameter;
        }
    }

    private static Parameter<NumericImpl> ParameterNum = 
        Parameter<NumericImpl>.NewParameter();

3)使Parameter类静态并在via static constructor中创建。

static partial  class Parameter<T> where T : AnAbstract
{
    public static string Name { get; set; }
    //etc
}

static partial class Parameter<T> where T : AnAbstract
{ 
    static Parameter ()
    {
        AnAbstract instance = (AnAbstract)Activator.CreateInstance(typeof(T));
        Parameter<T>.Name = instance.Name;
        //etc
    }
}

在上一个示例中,您可以像这样使用此类:

String someName = Parameter<NumericImpl>.Name;