简体   繁体   English

函数可以返回未知类型的通用类的实例吗?

[英]Can A Function Return An Instance Of Generic Class Of Unknown Type?

I have a utility class called ImageProperty which is used to store the type and value of a specific image property. 我有一个名为ImageProperty的实用程序类,用于存储特定图像属性的类型和值。

The type can only be one of the following enum values: 该类型只能是以下枚举值之一:

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

The values are all of different types ( Size , float , float , int , bool ). 这些值都是不同的类型( Sizefloatfloatintbool )。

A simplified form of my ImageProperty class is as follows: 我的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;
    }
}

Note the use of object for getting/setting the value (since the types vary). 请注意使用对象获取/设置值(因为类型不同)。

I want to make my class generic since I do not like using object so I make a few changes to the class and methods: 我想使类通用,因为我不喜欢使用对象,因此我对类和方法进行了一些更改:

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

I have a function in another class that needs to return an instance of ImageProperty based on the type given. 我在另一个类中有一个函数,需要根据给定的类型返回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);
        ...
        ...
    }
}

I am not sure of what return type to put for this method (hence the ????). 我不确定该方法要使用哪种返回类型(因此????)。

I can't just put: 我不能只说:

public ImageProperty getImageProperty(ImagePropertyType type, Bitmap bitMap)

because the ImageProperty class needs to be parameterized. 因为需要对ImageProperty类进行参数化。

Obviously, if the value type were always, lets say, int I would set the return type to: 显然,如果值类型始终是,可以说int我将返回类型设置为:

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

Is there a way to define the return type of getImageProperty to "any or unknown parameterized value"? 有没有一种方法可以将getImageProperty的返回类型定义为“任何或未知的参数化值”?

Something like: 就像是:

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

Is parameterizing the class is not a good idea since I don't know about the type of value that is going to be returned? 因为我不知道将返回的值的类型,所以对类进行参数化不是一个好主意吗?

Should I just make the ImageProperty class non-generic (like the first class in my post) and go back to using object for the return type and if I need to know the value type I can just get it using typeof? 我是否应该使ImageProperty类成为非泛型类(例如我的帖子中的第一个类),然后返回使用object作为返回类型?如果我想知道值类型,我可以使用typeof来获取它?

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

Thank you. 谢谢。

----UPDATE--------------------------------- ----更新---------------------------------

Based on Knaģis' suggestion and further reading I decided to keep the original class then make a generic class that extends ImageProperty: 根据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;
    }
}    

One thing, however. 一件事,但是。 I am getting a compiler warning that says: 我收到一个编译器警告,内容是:

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

I added the new keyword: 我添加了关键字:

public new T getPropertyValue() 公共新T getPropertyValue()

Strange, I never knew about the new keyword being used in a method declaration and how it's used. 奇怪,我从不知道方法声明中使用了new关键字以及如何使用它。 Anyone care to explain? 有人在乎解释吗?


In your case the only thing you can do is to ask for the method to return a certain type: 在您的情况下,您唯一可以做的就是要求该方法返回某种类型:

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

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

That type T must be known by the caller, otherwise the compiler won't be able to make sense of your code. 调用者必须知道T类型,否则编译器将无法理解您的代码。 If you don't know it always then your generic class must inherit from a non-generic base class and the method will then return the non-generic type that can be later cast to the specific generic implementation. 如果您并不总是知道它,那么您的泛型类必须从非泛型基类继承,然后该方法将返回非泛型类型,该类型以后可转换为特定的泛型实现。

// 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM