Пример #1
0
        public virtual void SetPropertyValue <TVal>(TVal value, [CallerMemberName] string prop = null)
        {
            var paths = Helpers.ParsePropertyParts(prop);

            if (paths.Length == 0)
            {
                return;
            }
            int lastIndex = 0;
            //check if last path was an indexer

            /*
             *   A=value -> Get Owner = this, owner["A"] = value
             *   A.B=value -> Get Owner = A, owner["B"] = value
             *   Item[A,B]=value -> Get Indexer = Item[A,B],indexer[A,B] = value
             *   A.Item[A,B]=value -> Get Indexer = Item[A,B], indexer [A,B] = value
             */
            var lastPath = paths[paths.Length - 1];

            if (lastPath.Contains("["))
            {
                //last part is an indexer
                lastIndex = paths.Length - 1;
            }
            else
            {
                lastIndex = paths.Length - 2;
            }
            DescribableObject curObj = this;

            //end loop before reaching last part
            for (int i = 0; i <= lastIndex; i++)
            {
                if (curObj == null)
                {
                    break;
                }
                //each iteration yields a curObj or an ownerIndexer
                var path     = paths[i];
                var purePath = path.Contains("[") ? path.Substring(0, path.IndexOf('[')) : path;
                if (purePath.Length == 0)
                {
                    purePath = "Item";
                }
                if (curObj.InternalDictionary.TryGetValue(purePath, out DescribableProperty dProperty))
                {
                    if (path.Contains("["))
                    {
                        IndexerDescriptorContainer idc;
                        if (dProperty.Value is IndexerDescriptorContainer)
                        {
                            idc = dProperty.Value as IndexerDescriptorContainer;
                        }
                        else if (dProperty.Value is DescribableObject dindexer)
                        {
                            idc = dindexer.InternalDictionary["Item"].Value as IndexerDescriptorContainer;
                            Console.WriteLine("A logically impossible case just happened ! please tell the developers (me) that they suck");
                        }
                        else
                        {
                            return;
                        }
                        //now we have the indexer container, curObj = result value, or either final value = result value
                        var pureIndexedParameters = path.Substring(path.IndexOf('[') + 1, path.Length - purePath.Length - 2);

                        var desc = idc.GetDescriptor(pureIndexedParameters, out var indices, out bool suc);
                        if (!suc)
                        {
                            return;
                        }
                        var matchDict = new MethodParameterValue[desc.Parameters.Length];
                        for (int j = 0; j < desc.Parameters.Length; j++)
                        {
                            var param = desc.Parameters[j];
                            matchDict[j] = new MethodParameterValue(param, indices[j]);
                        }
                        if (i == lastIndex)
                        {
                            //set indexer here
                            if (desc.IsReadOnly)
                            {
                                return;
                            }
                            curObj.Before_Set(path, value);
                            desc.SetValue(matchDict, value);
                            curObj.After_Set(path, value);
                            return;
                        }
                        else
                        {
                            //get owner object
                            var IndexerRes = desc.GetValue <object>(matchDict);
                            //check indexer result
                            if (IndexerRes is DescribableObject d)
                            {
                                curObj = d;
                            }
                            else
                            {
                                curObj = null;
                            }
                        }
                    }
                    else if (dProperty.Value is DescribableObject d)
                    {
                        curObj = d;
                    }
                    else
                    {
                        curObj = null;
                    }
                }
                else
                {
                    return;
                }
            }

            if (curObj == null)
            {
                return;
            }

            if (curObj.InternalDictionary.TryGetValue(lastPath, out var dp))
            {
                if (dp.IsReadOnly)
                {
                    return;
                }
                curObj.Before_Set(dp.Name, value);
                dp.Value = value;
                curObj.After_Set(dp.Name, value);
            }
            else
            {
                dp = new DescribableProperty(lastPath, false)
                {
                    Value = value
                };
                //unregistered property
                curObj.Before_Set(dp.Name, value);
                curObj.InternalDictionary[lastPath] = dp;
                curObj.After_Set(dp.Name, value);
            }
        }
Пример #2
0
        public virtual object GetPropertyValue([CallerMemberName] string prop = null)
        {
            var paths = Helpers.ParsePropertyParts(prop);

            if (paths.Length == 0)
            {
                return(null);
            }
            DescribableObject curObj   = this;
            object            finalVal = null;

            for (int i = 0; i < paths.Length; i++)
            {
                if (curObj == null)
                {
                    break;
                }
                //each iteration yields a finalVal and a curObj
                var path     = paths[i];
                var purePath = path.Contains("[") ? path.Substring(0, path.IndexOf('[')) : path;
                if (purePath.Length == 0)
                {
                    purePath = "Item";
                }
                if (curObj.InternalDictionary.TryGetValue(purePath, out DescribableProperty dProperty))
                {
                    if (path.Contains("["))
                    {
                        IndexerDescriptorContainer idc;
                        if (dProperty.Value is IndexerDescriptorContainer)
                        {
                            idc = dProperty.Value as IndexerDescriptorContainer;
                        }
                        else if (dProperty.Value is DescribableObject dindexer)
                        {
                            idc = dindexer.InternalDictionary["Item"].Value as IndexerDescriptorContainer;
                        }
                        else
                        {
                            return(null);
                        }
                        //now we have the indexer container, curObj = result value, or either final value = result value
                        var pureIndexedParameters = path.Substring(path.IndexOf('[') + 1, path.Length - purePath.Length - 2);
                        var desc = idc.GetDescriptor(pureIndexedParameters, out var vals, out bool suc);
                        if (!suc)
                        {
                            return(null);
                        }
                        var matchDict = new MethodParameterValue[desc.Parameters.Length];
                        for (int j = 0; j < desc.Parameters.Length; j++)
                        {
                            var param = desc.Parameters[j];
                            matchDict[j] = new MethodParameterValue(param, vals[j]);
                        }
                        var IndexerRes = desc.GetValue <object>(matchDict);
                        //check indexer result
                        if (IndexerRes is DescribableObject d)
                        {
                            curObj   = d;
                            finalVal = d;
                        }
                        else
                        {
                            curObj   = null;
                            finalVal = IndexerRes;
                        }
                    }
                    else if (dProperty.Value is DescribableObject d)
                    {
                        curObj   = d;
                        finalVal = d;
                    }
                    else
                    {
                        curObj   = null;
                        finalVal = dProperty.Value;
                    }
                }
                else
                {
                    //property doesn't exist
                    return(null);
                }
            }
            return(finalVal);
        }