开发者

I need a common class/interface for any .Net data type

I'm looking for a way to treat ALL .Net datatypes consistently so I can cre开发者_运维百科ate the pattern below where any type implementing IGetValue<out T> will cast to IGetValue<object>. For some reason, if T is a struct, it doesn't work and I don't understand why. Is there a way I can implement the following pattern??

public interface IGetValue<out T>
{
    T Value
    {
        get;
    }
}

public class GetValue<T> : IGetValue<T>
{
    public GetValue(T value)
    {
        _value = value;
    }

    private T _value;
    public T Value
    {
        get { return _value; }
    }
}


class Program
{
    static void Main(string[] args)
    {
        IGetValue<string> GetString = new GetValue<string>("Hello");
        IGetValue<int> GetInt = new GetValue<int>(21);

        //This works!!!
        if (GetString is IGetValue<object>)
        {
            Console.WriteLine("GetValue<string> is an IGetValue<object>");
        }
        else
        {
            Console.WriteLine("GetValue<string> is not an IGetValue<object>");
        }

        //This doesn't work!!! Why????
        if (GetInt is IGetValue<object>)
        {
            Console.WriteLine("GetValue<int> is an IGetValue<object>");
        }
        else
        {
            Console.WriteLine("GetValue<int> is not an IGetValue<object>");
        }

        Console.ReadKey();
    }
}

Edit:

I realize what I'm trying to accomplish here seems vague, but this is part of a larger design whose explanation would be too verbose. What I need is to have all of my IGetValue<T>s to share a common type or interface with a property named "Value" that returns an object. Why is the verbose part.


It doesn't work because generic variance doesn't apply to value types... they have different representations, whereas variance with reference types can happen without the CLR having to perform any conversions.

So for example, you can treat an IEnumerable<string> as an IEnumerable<object>, but you can't treat an IEnumerable<int> as an IEnumerable<object>.


I ended up solving my immediate need by creating a non-generic IGetValue interface and implementing it explicitly in the class. Here's the solution:

public interface IGetValue
{
    object Value
    {
        get;
    }
}

public interface IGetValue<out T>
{
    T Value
    {
        get;
    }
}

public class GetValue<T> : IGetValue<T>, IGetValue
{
    public GetValue(T value)
    {
        _value = value;
    }

    private T _value;
    public T Value
    {
        get { return _value; }
    }

    object IGetValue.Value
    {
        get { return _value; }
    }
}


class Program
{
    static void Main(string[] args)
    {
        IGetValue<string> GetString = new GetValue<string>("Hello");
        IGetValue<int> GetInt = new GetValue<int>(21);

        if (GetString is IGetValue)
        {
            Console.WriteLine("GetValue<string> is an IGetValue");
        }
        else
        {
            Console.WriteLine("GetValue<string> is not an IGetValue");
        }


        if (GetInt is IGetValue)
        {
            Console.WriteLine("GetValue<int> is an IGetValue");
        }
        else
        {
            Console.WriteLine("GetValue<int> is not an IGetValue");
        }

        Console.ReadKey();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜