2013-02-08 2 views
1

이것은 실제로 혼란스러워 보이지만 값으로 다른 클래스로 채워진 사전을 만들고 키로 문자를 사용하려고합니다. 그 사전에있는 키를 호출 할 때 "새로운 ClassInDictionary"를 입력하는 것처럼 행동 할 필요가 있습니다.C# 사전에 클래스 넣기 및 호출시 새 인스턴스 만들기

다른 블록을 정의하는 다른 기호로 텍스트 파일을 만들 수 있습니다. "나는 단순히 blockIdentifier을 [호출 할 필요가

public class BlockDirt : Block 
{ 
    public int hi; 

    public BlockDirt() 
     : base("Dirt Block.png", 0, 0, true) 
    { 
    } 
} 

:

blockIdentifier.Add("=", new BlockAir()); // Define which class corresponds to which letter 
blockIdentifier.Add("-", new BlockDirt()); 

for (int mapX = 0; mapX < mapWidth; mapX++) 
{ 
    for (int mapY = 0; mapY < mapHeight; mapY++) 
    { 
     try 
     { 
      Block block = blockIdentifier[mapSplit[mapY].Substring(mapX, 1)]; // Simply find which letter to use, let's pretend it's: "=" 
      // The line above should be creating a new instance of the class BlockAir             
      block.blockX = mapX * 45; 
      block.blockY = mapY * 45; 

      mapList[mapY, mapX] = block; 
     } 
     catch (Exception) 
     { 
     } 
    } 
} 

변수 blockIdentifier :

public static Dictionary<string, Block> blockIdentifier = new Dictionary<string, Block>(); 

그리고 BlockDirt 여기에 명확한 일을 돕는다

내 현재 코드입니다 = "] 클래스 BlockDirt() 클래스의 새 인스턴스를 가져 오려면 어떻게해야합니까?

+1

그리고 귀하의 질문은 무엇입니까? – Pete

+0

처음에 클래스를 어떻게 저장합니까? –

+0

죄송합니다. 중요한 부분을 정말로 잊어 버렸습니다. blockIdentifier [ "="]를 호출하고 클래스 BlockDirt() 클래스의 새 인스턴스를 가져와야합니다. –

답변

1

사전에 ConstructorInfo 개의 개체를 저장 한 다음 리플렉션을 통해 개체를 만들어이 작업을 수행 할 수 있습니다. 어쩌면 일종의 해커 일 수도 있지만, 제대로 작동 할 것이라고 생각합니다.

다음은 사전에서 StringBuilder 생성자를 사용하는 예입니다 (LINQPad에서이 결과를 볼 수 있음).

var creator = typeof(StringBuilder).GetConstructor(new Type[]{}); 
var dict = new Dictionary<string, ConstructorInfo>(); 

dict["a"] = creator; 

StringBuilder b = (StringBuilder)dict["a"].Invoke(new object[]{}); 
b.AppendLine("Hello World"); 
b.ToString().Dump(); 

그래서 귀하의 경우에, 당신은 당신의 다른 Block 개체에 대한 생성자를 원하는 :

var blockIdentifier = new Dictionary<string, ConstructorInfo>(); 
blockIdentifier["="] = typeof(BlockAir).GetConstructor(new Type[]{}); 
blockIdentifier["-"] = typeof(BlockDirt).GetConstructor(new Type[]{}); 
+0

Ehhh, 이것은 나에게 적합하지 않습니다. 내가 추천하는 다른 옵션은 무엇입니까? 필자가 정말로해야 할 일은 서로 다른 문자열을 가진 서로 다른 유형의 블록을 정의하는 것입니다. 이것은 텍스트를 포함하는 텍스트 파일을 읽을 수 있도록 예를 들어 있습니다. = - = - =, 이는 먼지, 공기, 먼지, 공기, 먼지로 해석됩니다. –

7

는 블록마다 또는의 단일 인스턴스를 다시 사용의 새로운 인스턴스를 만드시겠습니까 블록?

코드에서 매번 새로운 코드를 생성하려는 것처럼 보입니다. 그렇다면 한 가지 방법은 모든 블록이 Block (또는 좀 더 좋을 수도있는 IBlock)에서 상속받는 Dictionary<string, Func<Block>>으로 만드는 것입니다.

참고

+1

+1 - 신난다 - 나는 "Constructor"를 생각하고 있었지만 창조를위한 람다를 저장하는 것이 훨씬 더 좋은 방법이다. 잘 했어. – pstrjds

+0

하나에 있습니다! 완벽하고 대단히 감사하는 친구! –

+0

기본적으로 공장 사전을 만들었습니다. 기발한거야. 나는 그것을 좋아한다. – BTownTKD

0

I (오류에 대한 사과, 그래서 그 순간에 내가 dev에 액세스 없어요. 환경) BlockAir : IBlock

var blockLookup = new Dictionary<string, Func<IBlock>>(); 
blockLookup.Add("=",()=> new BlockAir()); 
blockLookup.Add("-",()=> new BlockDirt()); 

... 

mapList[x,y] = blockLookup[symbol](); 

... 

또는 그 라인을 따라 BlockDirt : IBlock을 가정 사전에 Type 값을 사용하는 가장 논리적 인 방법은

var blockIdentifier = new Dictionary<string, Type>(); 
blockIdentifier.Add("=", typeof(BlockDirt)); 
blockIdentifier.Add("-", typeof(BlockAir)); 

.... 

mapList[x,y] = blockIdentifier[symbol].GetConstructor(new Type[] { }).Invoke(null); 
관련 문제