일반 클래스 C#의 일반 방법에 대한 제약으로 사용 되었습니까?

StackOverflow https://stackoverflow.com/questions/313036

  •  10-07-2019
  •  | 
  •  

문제

내가 뭔가 잘못하고 있습니까 아니면 일반 클래스를 일반 방법의 제약으로 지정할 수 없습니까?

나는 제네릭을 가지고 놀았습니다 DB4O (오픈 소스 객체 데이터베이스) 및 테스트 프로그램 (아래 코드 참조)을 작성하여 일부 사용자 정의 된 일반 컬렉션을 저장하고 검색합니다.

일반적인 방법을 쓰려고합니다 (참조 getCollectionFromdb 아래) 데이터베이스에서 구체적으로 입력 된 컬렉션을 검색합니다. 불행히도 아래 코드는 라인에 대한 컴파일러 생성 오류를 반환합니다.

 MyCollection1 collection3 =
                  GetCollectionFromDb<MyCollection1>(Collection1Name);

오류 메시지는 다음과 같습니다.

The type 'GenericsTest.MyCollection1'cannot be used as type parameter 'T'
in the generic type or method 'GenericsTest.Program.GetCollectionFromDb<T>(string)'.
There is no implicit reference conversion from'GenericsTest.MyCollection1' to
'GenericsTest.MyCollectionBase<GenericsTest.MyCollection1>'.

나는 내가 잘못하고있는 일이나 어떻게이를 다르게 접근 할 수있는 방법에 대한 제안에 감사 할 것입니다.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Db4objects.Db4o;

 namespace GenericsTest 
    {
        public class Entity1
        {
            public string SomeProperty { get; set; }
        }

        public class Entity2
        {
            public string SomeProperty { get; set; }
        }

        public abstract class MyCollectionBase<T> : Collection<T>
        {
            protected MyCollectionBase() : this("") { }

            protected MyCollectionBase(string pCollectionName) 
            {
                CollectionName = pCollectionName; 
            }

            public string CollectionName { get; set; }
        }

        public class MyCollection1 : MyCollectionBase<Entity1>
        {
            public MyCollection1(string pCollectionName) :
                                          base(pCollectionName) { }

            public void DoSomeWorkOnCollection1() {}
        }

        public class MyCollection2 : MyCollectionBase<Entity2>
        {
            public MyCollection2(string pCollectionName) :
                                          base(pCollectionName) { }

            public void DoSomeWorkOnCollection2() { }
        }

        public class Program
        {
            public static IObjectContainer db = null;

            public static void Main(string[] args)
            {
                const string Collection1Name = "Entity1Collection";
                const string Collection2Name = "Entity2Collection";
                db = Db4oFactory.OpenFile("Test.db");

                Entity1 entity1 = new Entity1();
                MyCollection1 collection1 = new MyCollection1(Collection1Name);
                collection1.Add(entity1);
                db.Store(collection1);

                Entity2 entity2 = new Entity2();
                MyCollection2 collection2 = new MyCollection2(Collection2Name);
                collection1.Add(entity1);
                db.Store(collection2);

                db.Commit();
                db.Close();
                db = Db4oFactory.OpenFile("Test.db");

                MyCollection1 collection3 = 
                       GetCollectionFromDb<MyCollection1>(Collection1Name);
            }

            private static T GetCollectionFromDb<T>(string pCollectionName) 
                                                 where T : MyCollectionBase<T>
            {
                IList<T> queryResult = db.Query((T c) => 
                                         c.CollectionName == pCollectionName);
                if (queryResult.Count != 0) return queryResult[0];

                return null;
            }
        } 
    }
도움이 되었습니까?

해결책

T를 따르십시오 :

    // ...
    {
       //...
       MyCollection1 collection3 = GetCollectionFromDb<MyCollection1>(Collection1Name);

    }

    private static T GetCollectionFromDb<T>(string pCollectionName) where T : MyCollectionBase<T>
    {
        IList<T> queryResult = db.Query((T c) => c.CollectionName == pCollectionName);
        if (queryResult.Count != 0) return queryResult[0];
        return null;
    }

다음으로 번역됩니다.

    private static MyCollection1 GetCollectionFromDb<MyCollection1>(string pCollectionName) where T : MyCollectionBase< MyCollection1 >
    {
        IList< MyCollection1 > queryResult = db.Query((MyCollection1 c) => c.CollectionName == pCollectionName);
        if (queryResult.Count != 0) return queryResult[0];
        return null;
    }

MyCollection1이 MyCollectionBase <Entity1>에서 파생되기 때문에 MyCollectionBase <MyCollection1>이기 때문에 원하는 것이 아니기 때문에 오류가 발생했습니다. 제약 조건이 작동하려면 제 2 형 식별자를 사용하여 일반 컬렉션에 사용되는 유형을 표현해야 할 것입니다.

다른 팁

유형은 제약 조건을 충족하지 않습니다. 당신은 제공했습니다 MyCollection1 에서 파생됩니다 MyCollection<Entity1>. 그러나 이것이 그것이 파생된다는 것을 의미하지는 않습니다 MyCollection<MyCollection1>.

아마도 하나 대신 두 가지 유형 매개 변수에 대한 제약 조건을 표현하려고합니다.

private static T GetCollectionFromDb<T, U>(string pCollectionName) 
                                             where T : MyCollectionBase<U>

그런 다음 다음으로 호출하십시오.

GetCollectionFromDb<MyCollection1, Entity1>(Collection1Name);

그렇다면 트릭을 수행하지 않으면 이유를 알려주십시오.

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