实例化给定通用抽象类型的类 [英] Instantiating a class given a generic abstract type

查看:48
本文介绍了实例化给定通用抽象类型的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用此模型:

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

有了这个,我假装定义了一个类的层次结构,为此我可以拥有一些抽象属性( Name Description IsNumeric )在层次结构的最后,应该有一些类强制定义这些属性;在 ANumericAbstract 的情况下,它们应具有其他特定属性,例如 Min Max .

With this, I pretend to define a hierarchy of classes for which I can have some abstract properties (Name,Description,IsNumeric) and at the end of the hierarchy there should be some classes which mandatorily define those properties; in the case of ANumericAbstract they should have additional specific properties, e.g. Min and Max.

现在是问题所在.

我希望能够创建 Parameter 的实例,这些实例采用通用的 AnAbstract 并从中读取一些值以填充 Parameter 属性,àla

I'm attemtping to be able to create instances of Parameter which take a generic AnAbstract and read from it some values to fill in the Parameter properties, à la

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

其中 Parameter 构造函数将采用传递的类型并填入空格".换句话说,我正在尝试类似的事情:

where a Parameter constructor would take in the passed type and "fill in the blanks". In other words, I'm trying something like:

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?:-)此时,只需执行

Obviously the syntax is invalid, but I'm not sure if I'm going in the right direction. Is there some Generics syntax that I'm not using properly? Should I just be done with it and use Getters and Setters à la Java? :-) At this point, just doing the

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

可能看起来更明智...

might seem more sensible...

推荐答案

首先,您不应该在属性上使用 New 关键字.考虑虚拟关键字:

Firstly you should not use New keyword on your properties. Consider virtual keyword:

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实例.

1) You can place an instance of you type in Parameter constructor and have Parameter instance.

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

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

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

2) The second way is to use reflection to create an instance of object with initial parameters.

    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类设为静态并通过静态构造函数创建.

3) Make Parameter class static and create in 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
    }
}

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

In the last example you can use this class like this:

String someName = Parameter<NumericImpl>.Name;

这篇关于实例化给定通用抽象类型的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆