Приведение типа, возвращаемого анонимным методом - PullRequest
0 голосов
/ 13 июня 2011

У меня есть объект "ConnectableProperty", который подключает одно свойство к другому и требует, чтобы я передавал его Func. Сейчас у меня 2 типа на данный момент - Скаляр и Цвет. Оба могут быть преобразованы друг в друга через явные операторы. По какой-то причине я не могу кормить от Func<double, double, Scalar> до Func<double, double Color>, хотя Скаляр может кастовать в Color. В чем дело?

Чтобы уточнить, я добавил код. Обратите внимание, что подключаемые свойства являются «входами». Выходы (которые могут быть подключены) являются методами, которые имеют эту подпись.

Вот ConnectableProperty

public sealed class ConnectableProperty<T> : IEquatable<T>, IGetXY<T> where T : IValue<T>
{
    private T _value;
    public T Value { get { return _value; } set { _value = value; } }

    public INode ParentNode { get; private set; }
    public ValueConnection<T> Connection { get; set; }
    public INode ConnectionFrom { get { return !IsConnected ? null : Connection.FromNode; } }
    public bool IsConnected { get { return Connection == null; } }

    public ConnectableProperty(INode parentNode, T value)
    {
        ParentNode = parentNode;
        _value = value;
    }

    public T GetXY(double x, double y)
    {
        return IsConnected 
            ? Connection.FromValue(x, y) 
            : _value;
    }

    public void Connect(INode fromNode, Func<double, double, T> getXY)
    {
        Connection = new ValueConnection<T>(fromNode, ParentNode, getXY, this);
    }

    public void Disconnect()
    {
        Connection = null;
    }

    public bool Equals(T other)
    {
        return _value.Equals(other);
    }

    public static implicit operator T(ConnectableProperty<T> connectableProperty)
    {
        return connectableProperty._value;
    }
}

И ValueConnection:

public class ValueConnection<T>
{
    public INode FromNode { get; private set; }
    public INode ToNode { get; private set; }

    public Func<double, double, T> FromValue { get; private set; }
    public ConnectableProperty<T> ToValue { get; private set; }

    public ValueConnection(INode fromNode, INode toNode, Func<double, double, T> fromValue, ConnectableProperty<T> toValue)
    {
        // TODO: Implement INPC type thing

        FromNode = fromNode;
        ToNode = toNode;

        FromValue = fromValue;
        ToValue = toValue; 
    }
}

Ответы [ 3 ]

6 голосов
/ 13 июня 2011

Джон прав; просто чтобы добавить к этому:

Во-первых, причина, по которой это не работает, в том, что нет места, где существует преобразование. Предположим, у вас есть:

Func<int> f1 = ()=>1;
Func<double> f2 = f1;

Предположим, это было законно. Где-то компилятор C # должен сгенерировать инструкцию , которая преобразует int в double. Куда? Не в лямбде; эта вещь должна возвращать int, когда вызывается f1. Но не в f2 также, потому что f1 ссылка идентична для f1. Есть два возможных решения: сделать это незаконным или сделать так, чтобы это действительно означало:

f2 = ()=>(double)f1();

так, чтобы f1 и f2 больше не были идентичными. Мы выбрали первое решение.

Во-вторых, это допустимо в C # 4, если возвращаемые типы имеют неявное преобразование reference между ними. Нам не нужно выдавать какие-либо инструкции для неявного преобразования ссылок; это законно без какого-либо специального кода.

5 голосов
/ 13 июня 2011

Нет, вы не сможете выполнить это преобразование напрямую, и я не ожидал бы, что смогу - но вы могли бы легко написать пару методов, чтобы выполнить это для вас:

public Func<double, double, Scalar> ConvertFunc(Func<double, double, Color func)
{
    return (x, y) => (Scalar) func(x, y);
}

public Func<double, double, Color> ConvertFunc(Func<double, double, Scalar func)
{
    return (x, y) => (Color) func(x, y);
}

Когда у вас есть делегат, который должен возвращать определенный тип, он должен иметь возможность вызывать напрямую и возвращать значение соответствующего типа. Вызывающий не должен знать, что, несмотря на то, что у него есть Func<X>, если он хочет получить X, ему нужно будет привести результат к X.

0 голосов
/ 13 июня 2011

Не будет ли работать просто используя явное приведение внутри тела функции?Тогда вы можете использовать только один тип функции - не требуется кастинг

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...