문제

C#있 확장 속성?

예를 들어,추가할 수 있는 확장성 DateTimeFormatInfoShortDateLongTimeFormat 로 돌아온 ShortDatePattern + " " + LongTimePattern?

도움이 되었습니까?

해결책

아니요 C# 3.0에는 존재하지 않으며 4.0에 추가되지 않습니다. C#에 대한 기능 목록에 있으므로 향후 날짜에 추가 될 수 있습니다.

이 시점에서 당신이 할 수있는 최선은 getxxx 스타일 확장 방법입니다.

다른 팁

아니, 그들은 존재하지 않습니다.

나는 C# 팀이 한 시점에서 그들을 고려하고 있다는 것을 알고 있습니다 (또는 적어도 Eric Lippert는 확장 생성자 및 운영자와 함께 (머리를 돌리는 데 시간이 걸릴 수도 있지만 멋지다 ...) 'T는 그들이 C# 4의 일부가 될 것이라는 증거를 보았습니다.

편집 : C# 5에 나타나지 않았으며 2014 년 7 월 현재 C# 6에있을 것 같지 않습니다.

에릭 립퍼트, 2012 년 11 월부터 Microsoft의 C# 컴파일러 팀의 주요 개발자는 2009 년 10 월에 이에 대해 블로그를 작성했습니다.

잠시 그것은 여전히지 않는 지원자의 의 Roslyn 컴파일러는...

지금까지 확장 속성으로 볼 수 없는 귀중한 충분히 포함되기 이전 버전에서는 C#의 표준입니다. C#7C#8.0 이것을 보았으로 제안 챔피언어지지 않는 아직 출시,대부분의 모든기 때문이 있을 경우에도 이미 구현을 만들고 싶어,그것은 오른쪽에서 시작합니다.

하지만 그것은 것입니다...

extension 원 항목에 C#7 일 목록 그래서 지원할 수도 있습니다.의 현재 상태를 확장 속성에서 찾을 수 있습니다 Github 에서 관련 항목.

그러나,거기에 더 많은 유망한 항목에서는 "모든 것을 확장" 에 초점을 맞춘 특히 속성과 정 클래스 또는 필드가 있습니다.

또한 해결 방법을 사용할 수 있습

로 지정된 이 문서, 사용할 수 있습니다 TypeDescriptor 있는 기능을 연결하는 특성을 객체를 인스턴스에서 runtime.그러나,그것은 구문을 사용하여 표준의 속성입니다.
그것은 조금 다르에서의 문법을 추가하는 가능성을 정의하는 확장된 속성
string Data(this MyClass instance) 별칭으로 확장을 위한 방법
string GetData(this MyClass instance) 으로 데이터를 저장하으로 클래스입니다.

나는 희망 C#7 를 제공할 것이 전체 추천 확장자는 모든 것(속성과 분야),그러나 그 시점에만 시간이 말해 줄 것이다.

고 자유롭게 기여 소프트웨어의 내에서 올 것입니다.

업데이트:August2016

Dotnet 팀 게시 what's new in C#7.0 부 의견의 Mads Torgensen:

확장 속성:리(다) 인턴 구현을 통해 그들을 여름 실험으로 다른 종류의 확장 회원입니다.우리는 유지에 관심이 있지만,그것은 큰 변화는 우리가 이 필요하다는 자신감을 느낄 가치가 있습니다.

그것은 보인다는 확장성과 다른 회원들은 여전히 좋은 후보에서 포함되는 미래의 방출 Roslyn,하지만 어쩌면 7.0 하나입니다.

업데이트:수도 있습 2017

Extension 원 가 폐쇄되었으로 중복의 확장자는 모든 문제 는 많다.주요 토론에 대한 사실 유형 확장 넓은 의미에서.이 기능은 지금 추적 여기는 제안 과에서 제거되었습니다 7.0 이정표.

업데이트:월,2017-C#8.0 제안 기능

는 동안 그것은 여전히 남아 있만 제안 기능,이제 우리는 명확하게 볼 수는 무엇이 있을까 그것의 구문입니다.유지 하는 마음에 이은 새로운 구문을 연장을 위한 방법뿐만 아니라:

public interface IEmployee 
{
    public decimal Salary { get; set; }
}

public class Employee
{
    public decimal Salary { get; set; }
}

public extension MyPersonExtension extends Person : IEmployee
{
    private static readonly ConditionalWeakTable<Person, Employee> _employees = 
        new ConditionalWeakTable<Person, Employee>();


    public decimal Salary
    {
        get 
        {
            // `this` is the instance of Person
            return _employees.GetOrCreate(this).Salary; 
        }
        set 
        {
            Employee employee = null;
            if (!_employees.TryGetValue(this, out employee)
            {
                employee = _employees.GetOrCreate(this);
            }
            employee.Salary = value;
        }
    }
}

IEmployee person = new Person();
var salary = person.Salary;

비슷한 부분 클래스하지만,컴파일된 별도의 클래스/형식에서 다른 어셈블리입니다.참고 당신은 또한 추가 할 수 있는 정적 멤버와 운영자 이 방법입니다.에서 언급했듯이 Mads Torgensen 팟캐스트, 장이 없는 상태(할 수 없습니다 그래서 추가설 인스턴스가 구성원은 클래스)를 의미할 수 없습니다 추가 개인스턴스는 데이터에 연결된 인스턴스.는 이유에 대해 호출되는 것을 의미를 관리하는 내부적으로 사전하고 어려울 수 있습(메모리 관리,etc...).이를 위해,계속 사용할 수 있습니다 TypeDescriptor/ConditionalWeakTable 기술 앞에서 설명과 함께 제공 확장,숨깁니다 그것은 아래 객실 tv 에서 위성 채널을 시청하실 수.

구문은 여전히 변경될 수 있으로 의미이 문제.예를 들어, extends 대체될 수 있었습니다 for 어떤 느낄 수 있습니다 더 자연스럽고 적 java 관련이 있습니다.

업데이트 2018 년 월-역할,확장고 및 정 인터페이스 구성원

확장의 모든 것 그것을 만들지 않았 C#8.0 기 때문에,일부 의 단점을 설명의 끝으로 이 GitHub 티켓.그런데 거기에서 제가 탐구를 위해 설계된다. ,Mads Torgensen 무엇인지 설명하는 역할과 확장 고 그들이 어떻게 다릅니다:

의 역할을 허용될 인터페이스를 구현에 특정 값을 지정 유형입니다.확장을 허용될 인터페이스를 구현에 대한 모든 값의 지정된 형식,내의 특정 지역의 코드입니다.

에서 볼 수 있는 분의 이전 계획안에서 두 개의 사용 사례를 보여주고 있습니다.이 새로운 구문을 위해 확장 이트:

public extension ULongEnumerable of ulong
{
    public IEnumerator<byte> GetEnumerator()
    {
        for (int i = sizeof(ulong); i > 0; i--)
        {
            yield return unchecked((byte)(this >> (i-1)*8));
        }
    }
}

다음을 할 수 있다:

foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
    WriteLine($"{e.Current:X}");
}

정적 인터페이스:

public interface IMonoid<T> where T : IMonoid<T>
{
    static T operator +(T t1, T t2);
    static T Zero { get; }
}

추가 확장성int 과 치료 intIMonoid<int>:

public extension IntMonoid of int : IMonoid<int>
{
    public static int Zero => 0;
}

업데이트 (감사합니다 @chaost 이 업데이트를 지적하려면) :

Mads Torgersen : "Extension 모든 것이 C# 8.0으로 만들지 않았습니다. 언어의 더 많은 미래에 대한 매우 흥미로운 토론에서“잡힌”것입니다. 이제 우리는 그것을 추가하지 않기를 원합니다. 미래의 가능성을 억제하는 방법. 때로는 언어 디자인이 매우 긴 게임입니다! "

원천: 댓글 섹션 https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/


나는 수년에 걸쳐이 질문을 몇 번이나 몇 번이나 구현하기를 희망하면서 몇 번이나 횟수를 세지 않았다.

글쎄, 마침내 우리는 모두 기뻐할 수 있습니다! Microsoft는 다가오는 C# 8 릴리스에서 이것을 소개 할 예정입니다.

그래서 이것을하는 대신 ...

public static class IntExtensions
{
   public static bool Even(this int value)
   {
        return value % 2 == 0;
   }
}

우리는 마침내 그렇게 할 수있을 것입니다 ...

public extension IntExtension extends int
{
    public bool Even => this % 2 == 0;
}

원천: https://blog.ndepend.com/c-8-0-features-glimpse-future/

@psyonity가 언급했듯이 컨디셔닝 웨이크 테이블을 사용하여 기존 객체에 속성을 추가 할 수 있습니다. 동적 ExpandooBject와 결합하여 몇 줄로 동적 확장 속성을 구현할 수 있습니다.

using System.Dynamic;
using System.Runtime.CompilerServices;

namespace ExtensionProperties
{
    /// <summary>
    /// Dynamically associates properies to a random object instance
    /// </summary>
    /// <example>
    /// var jan = new Person("Jan");
    ///
    /// jan.Age = 24; // regular property of the person object;
    /// jan.DynamicProperties().NumberOfDrinkingBuddies = 27; // not originally scoped to the person object;
    ///
    /// if (jan.Age &lt; jan.DynamicProperties().NumberOfDrinkingBuddies)
    /// Console.WriteLine("Jan drinks too much");
    /// </example>
    /// <remarks>
    /// If you get 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' you should reference Microsoft.CSharp
    /// </remarks>
    public static class ObjectExtensions
    {
        ///<summary>Stores extended data for objects</summary>
        private static ConditionalWeakTable<object, object> extendedData = new ConditionalWeakTable<object, object>();

        /// <summary>
        /// Gets a dynamic collection of properties associated with an object instance,
        /// with a lifetime scoped to the lifetime of the object
        /// </summary>
        /// <param name="obj">The object the properties are associated with</param>
        /// <returns>A dynamic collection of properties associated with an object instance.</returns>
        public static dynamic DynamicProperties(this object obj) => extendedData.GetValue(obj, _ => new ExpandoObject());
    }
}

사용 예제는 XML 주석에 있습니다.

var jan = new Person("Jan");

jan.Age = 24; // regular property of the person object;
jan.DynamicProperties().NumberOfDrinkingBuddies = 27; // not originally scoped to the person object;

if (jan.Age < jan.DynamicProperties().NumberOfDrinkingBuddies)
{
    Console.WriteLine("Jan drinks too much");
}

jan = null; // NumberOfDrinkingBuddies will also be erased during garbage collection

최근에 이것을 필요로했기 때문에 다음의 답변의 출처를 보았습니다.

C# 속성을 추가하여 클래스를 확장합니다

보다 역동적 인 버전을 만들었습니다.

public static class ObjectExtenders
{
    static readonly ConditionalWeakTable<object, List<stringObject>> Flags = new ConditionalWeakTable<object, List<stringObject>>();

    public static string GetFlags(this object objectItem, string key)
    {
        return Flags.GetOrCreateValue(objectItem).Single(x => x.Key == key).Value;
    }

    public static void SetFlags(this object objectItem, string key, string value)
    {
        if (Flags.GetOrCreateValue(objectItem).Any(x => x.Key == key))
        {
            Flags.GetOrCreateValue(objectItem).Single(x => x.Key == key).Value = value;
        }
        else
        {
            Flags.GetOrCreateValue(objectItem).Add(new stringObject()
            {
                Key = key,
                Value = value
            });
        }
    }

    class stringObject
    {
        public string Key;
        public string Value;
    }
}

아마도 개선 될 수 있습니다 (문자열 대신 이름 지정, 동적). 현재 CF 3.5에서 Hacky ConditionalWeakTable과 함께 사용합니다 (https://gist.github.com/jan-willemdebruyn/db79dd6fdef7b9845e217958db98c4d4)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top