2013-03-26 111 views
-1

採用這種模式:一個類實例化給定一個通用的抽象類型

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

現在是這個問題。

我attemtping能夠創造出採取通用AnAbstractParameter實例,並從中讀取一些值填寫Parameter性質,點菜

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, /* ... */ }; 

似乎更爲明智......

+3

嗯,第一個問題:該方法'NewParameter'是靜態的,你不能引用實例成員('this.Name '例如,這是非靜態的)從靜態上下文。它不應該是'Parameter.Name',使用上面創建的行的對象嗎? – 2013-03-26 12:34:34

+2

你想用現實世界中的代碼實現什麼?我有一個預感,接口可能是更好的工具。 – Alex 2013-03-26 12:54:04

回答

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)您在參數的構造類型和參數有例如你可以把一個實例。

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)使參數類爲靜態並通過靜態構造函數創建。

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;