【问题标题】:Can A Function Return An Instance Of Generic Class Of Unknown Type?函数可以返回未知类型的泛型类的实例吗?
【发布时间】:2013-10-10 15:28:28
【问题描述】:

我有一个名为 ImageProperty 的实用程序类,用于存储特定图像属性的类型和值。

类型只能是以下枚举值之一:

public enum ImagePropertyType { SIZE, H_RES, V_RES, BIT_COUNT, IS_ALPHA }

这些值都是不同的类型(Sizefloatfloatint布尔)。

我的 ImageProperty 类的简化形式如下:

public class ImageProperty
{
    private ImagePropertyType type;
    private object value;

    public ImageProperty(ImagePropertyType type, object value)
    {
        this.type = type;
        this.value = value;
    }

    public ImagePropertyType getType()
    {
        return this.type;
    }

    public void setType(ImagePropertyType type)
    {
        this.type = type
    }

    public object getValue()
    {
        return this.value;
    }        

    public void setValue(object value)
    {
        this.value = value;
    }
}

注意使用 object 来获取/设置值(因为类型不同)。

我想让我的类通用,因为我不喜欢使用对象,所以我对类和方法进行了一些更改:

public class ImageProperty<T>
{
    ...
    private T value;
    ...
    public ImageProperty(ImagePropertyType type, T value)
    ...
    public T getValue()
    ...
    public void setValue(T value)
    ...
}    

我在另一个类中有一个函数,它需要根据给定的类型返回 ImageProperty 的实例。

public ???? getImageProperty(ImagePropertyType type, Bitmap bitMap)
{
    switch(type)
    {     
        case SIZE:
            return new ImageProperty<Size>(type, bitMap.Size);
        case H_RES:
            return new ImageProperty<float>(type, bitMap.HorizontalResolution);
        case V_RES:                            
            return new ImageProperty<float>(type, bitMap.VerticalResolution);
        ...
        ...
    }
}

我不确定该方法的返回类型是什么(因此是 ????)。

我不能只说:

public ImageProperty getImageProperty(ImagePropertyType type, Bitmap bitMap)

因为 ImageProperty 类需要参数化。

显然,如果值类型总是,比如说,int,我会将返回类型设置为:

public ImageProperty<int> getImageProperty(ImagePropertyType type, Bitmap bitMap)

有没有办法将 getImageProperty 的返回类型定义为“任何或未知的参数化值”?

类似:

public ImageProperty<?> getImageProperty(ImagePropertyType type, Bitmap bitMap)

参数化类不是一个好主意,因为我不知道要返回的值的类型吗?

我是否应该将 ImageProperty 类设为非泛型(如我帖子中的第一个类)并返回使用 object 作为返回类型,如果我需要知道值类型,我可以使用它类型?

object value = getImageProperty(ImagePropertyType.SIZE, Bitmap bitMap).getValue();
Type t = typeof(value);

谢谢。

----更新---------------------------------

根据 Knaģis 的建议和进一步阅读,我决定保留原始类,然后创建一个扩展 ImageProperty 的通用类:

public class ImageProperty<T> : ImageProperty
{
    private T propertyValue;

    public ImageProperty()
        : base()
    {
    }

    public ImageProperty(ImagePropertyType propertyType, T propertyValue)
        : base(propertyType, propertyValue)
    {
        this.propertyValue = propertyValue;
    }

    public T getPropertyValue()
    {
        return propertyValue;
    }

    public void setPropertyValue(T propertyValue)
    {
        this.propertyValue = propertyValue;
    }
}    

不过,有一件事。我收到一个编译器警告,上面写着:

ImageProperty<T>.getPropertyValue() hides inherited member ImageProperty.getPropertyValue(). Use the new keyword if hiding was intended.

我添加了 new 关键字:

public new T getPropertyValue()

奇怪,我从来不知道在方法声明中使用了 new 关键字以及它是如何使用的。有人愿意解释吗?


【问题讨论】:

  • new 关键字仅用于开发人员可以通知编译器您实际上打算让该方法与基本方法具有相同的名称(新方法无法访问) .即使没有关键字,该方法的工作原理也是一样的。

标签: c# class generics undefined parameterized


【解决方案1】:

在你的情况下,你唯一能做的就是要求方法返回某种类型:

public ImageProperty<T> getImageProperty<T>(ImagePropertyType type, Bitmap bitMap)

// call the method
ImageProperty<int> result = obj.getImageProperty<int>(ImagePropertyType.SIZE, bitmap).

调用者必须知道该类型T,否则编译器将无法理解您的代码。如果您不总是知道它,那么您的泛型类必须继承自非泛型基类,然后该方法将返回非泛型类型,该类型稍后可以转换为特定的泛型实现。

// class
public class ImageProperty<T> : ImageProperty {}

// and methods that can be used (you can only use one of these unless you rename one)
public ImageProperty<T> getImageProperty<T>(ImagePropertyType type, Bitmap bitMap)
public ImageProperty getImageProperty(ImagePropertyType type, Bitmap bitMap)

【讨论】:

  • @p.s.w.g 我也想说同样的话。 ImagePropertyType 是一个枚举。
  • 我正在做 Knagis 在他最后一段中所说的。我正在创建一个非泛型基类,然后让泛型类继承自它。
  • @p.s.w.g - 是的,你是对的,重写答案以更好地应用于问题中使用的类型
  • Knaģis,请查看我在底部更新部分下的更新帖子,看看我决定做什么。正如您所建议的那样,我将 ImageProperty 设为基类,然后创建了另一个类 ImageProperty 来扩展它。
  • @Knaģis 这是为了更正,但您可能应该演示如何实现ImageProperty&lt;T&gt; : ImageProperty(隐藏基本方法)。
猜你喜欢
  • 1970-01-01
  • 2021-10-04
  • 2021-02-05
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多