문제

C#에는 Python과 같은 것이 있습니까? __getattr__?

많은 속성을 가진 클래스가 있으며 모두 동일한 액세서 코드를 공유합니다. 파이썬과 마찬가지로 개별 액세서를 완전히 떨어 뜨릴 수 있기를 원합니다.

내 코드는 다음과 같습니다.

class Foo
{
    protected bool Get(string name, bool def)
    {
        try {
            return client.Get(name);
        } catch {
            return def;
        }
    }

    public bool Bar
    {
        get { return Get("bar", true); }
        set { client.Set("bar", value); }
    }

    public bool Baz
    {
        get { return Get("baz", false); }
        set { client.Set("baz", value); }
    }
}

그리고 여기에 내가 원하는 것이 있습니다.

class Foo
{
    public bool Get(string name)
    {
        try {
            return client.Get(name);
        } catch {
            // Look-up default value in hash table and return it
        }
    }

    public void Set(string name, object value)
    {
        client.Set(name, value)
    }
}

전화하지 않고 C#에서 이것을 달성 할 수있는 방법이 있습니까? Get 곧장?

감사,

도움이 되었습니까?

해결책

아니요. C#은 반사를 지원하지만 읽기 전용 (로드 된 어셈블리의 경우)입니다. 즉, 방법, 속성 또는 기타 메타 데이터를 변경할 수 없습니다. 당신은 할 수 있습니다 동적 속성을 만듭니다, 그것을 부르는 것은 그리 편리하지 않을 것입니다 - 그것은 당신의 사용보다 더 나빠질 것입니다 Get 방법. 사용을 제외하고 Dictionary<string, object> 그리고 당신의 수업의 인덱서, 당신이 할 수있는 일이 많지 않습니다. 어쨌든, 많은 속성이 있다면 사전을 더 잘하지 않습니까?

Python은 속성이 "Compile-Time"(또는 적어도로드 타임)에 존재하는지 확인하지 않습니다. C#. 그것은 두 언어의 근본적인 차이입니다. 파이썬에서는 할 수 있습니다.

class my_class:
    pass

my_instance = my_class()
my_instance.my_attr = 1
print(my_instance.my_attr)

C#에서는 C#이 실제로 이름이 확인되므로 그렇게 할 수 없습니다. my_attr 컴파일 타임에 존재합니다.

다른 팁

확실하지 않지만 아마도 버전 4.0의 동적 기능이 도움이 될 것입니다. 그래도 기다려야 할 것입니다 ...

물어봐도 되나요: 개별 속성을 원하지 않습니까? 이것이 바로 객체와 관련된 데이터를 표현하는 관용적 인 .NET 방법입니다.

개인적으로 데이터가 드물지 않다고 가정하면 속성을 유지하고 전반적인 메소드를 사용하여 반사됩니다. 이렇게하면 컴파일 된 코드가 최대한 빨리 만들어집니다.

    protected T Get<T>(string name, T @default)
    {
        var prop = GetType().GetProperty(name);
        if(prop == null) return @default;
        return (T) prop.GetValue(this, null);
    }

물론, 속성 자체가 정의되는 속성에 신경 쓰지 않으면 인덱서와 조회 (예 : 사전)는 괜찮을 것입니다. PostSharp와 함께 할 수있는 일들도 일련의 속성을 속성 백으로 바꾸는 것도 있습니다. 아마도 그만한 가치가 없습니다.

데이터 바인딩 및 런타임 검색에 사용할 수있는 속성을 원하지만 컴파일 타임에 정의 할 수없는 경우 동적 유형 설명자를 살펴 봐야합니다. 어느 하나 ICustomTypeDescriptor 또는 TypeDescriptionProvider - 상당한 작업이지만 매우 다재다능합니다 (더 많은 정보를 원한다면 알려주세요).

이것은 동적 속성 이름을 가진 파이썬에서 얻는 것과 동일하지 않지만 유용 할 수 있습니다.

using System;
using System.Collections.Generic;

namespace Program
{
    class Program
    {
        static void Main(string[] args)
        {
            MyList<int> list = new MyList<int>();
            // Add a property with setter.
            list["One"] = 1;
            // Add a property with getter which takes default value.
            int two = list["Two", 2];
            Console.WriteLine("One={0}", list["One"]);
            Console.WriteLine("Two={0} / {1}", two, list["Two"]);
            try
            {
                Console.WriteLine("Three={0}", list["Three"]);
            }
            catch
            {
                Console.WriteLine("Three does not exist.");
            }
        }
        class MyList<T>
        {
            Dictionary<string, T> dictionary = new Dictionary<string,T>();

            internal T this[string property, T def]
            {
                get
                {
                    T value;
                    if (!dictionary.TryGetValue(property, out value))
                        dictionary.Add(property, value = def);
                    return value;
                }
            }
            internal T this[string property]
            {
                get
                {
                    return dictionary[property];
                }
                set
                {
                    dictionary[property] = value;
                }
            }
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top